Separate into k_pwrlv.c, add defines to reduce amount of magic numbers

This commit is contained in:
TehRealSalt 2019-09-23 08:26:42 -04:00
parent 9e587f4d0d
commit 38bb44e732
16 changed files with 494 additions and 431 deletions

View file

@ -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 \

View file

@ -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"

View file

@ -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;

View file

@ -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);

View file

@ -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?

View file

@ -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);

View file

@ -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)<<FRACBITS) / 5000;
for (j = 3; j < 10; j++) // Just skipping to 3 since 0 thru 2 will always just add 0...
{
fixed_t f = abs(x - ((j-4)<<FRACBITS));
fixed_t add;
if (f >= (2<<FRACBITS))
{
continue; //add = 0;
}
else if (f >= (1<<FRACBITS))
{
fixed_t f2 = (2<<FRACBITS) - f;
add = FixedMul(FixedMul(f2, f2), f2) / 6;
}
else
{
add = ((3*FixedMul(FixedMul(f, f), f)) - (6*FixedMul(f, f)) + (4<<FRACBITS)) / 6;
}
increment += (add * control[j]);
}
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) // 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];

View file

@ -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

289
src/k_pwrlv.c Normal file
View file

@ -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)<<FRACBITS) / PWRLVRECORD_DEF;
for (j = 3; j < 10; j++) // Just skipping to 3 since 0 thru 2 will always just add 0...
{
fixed_t f = abs(x - ((j-4)<<FRACBITS));
fixed_t add;
if (f >= (2<<FRACBITS))
{
continue; //add = 0;
}
else if (f >= (1<<FRACBITS))
{
fixed_t f2 = (2<<FRACBITS) - f;
add = FixedMul(FixedMul(f2, f2), f2) / 6;
}
else
{
add = ((3*FixedMul(FixedMul(f, f), f)) - (6*FixedMul(f, f)) + (4<<FRACBITS)) / 6;
}
increment += (add * control[j]);
}
return (INT16)(increment >> 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<<FRACBITS)/10);
encore = M_RandomChance(FRACUNIT>>2);
break;
case 1:
hardmode = M_RandomChance((3<<FRACBITS)/10);
encore = false;
break;
case 0:
default:
hardmode = encore = false;
break;
}
if (cv_speedscramble.value)
speedscramble = (hardmode ? 2 : 1);
else
speedscramble = -1;
if (cv_encorescramble.value)
encorescramble = (encore ? 1 : 0);
else
encorescramble = -1;
}
break;
default:
break;
}
}
void K_PlayerForfeit(UINT8 playernum, boolean pointloss)
{
UINT8 p = 0;
INT32 powertype = PWRLV_DISABLED;
UINT16 yourpower = PWRLVRECORD_DEF;
UINT16 theirpower = PWRLVRECORD_DEF;
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 = PWRLV_RACE;
else if (G_BattleGametype())
powertype = PWRLV_BATTLE;
if (powertype == PWRLV_DISABLED) // 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 = PWRLVRECORD_DEF;
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 > 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!
}
}

31
src/k_pwrlv.h Normal file
View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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") : ""

View file

@ -34,6 +34,9 @@
#include "p_slopes.h"
#endif
// SRB2Kart
#include "k_pwrlv.h"
savedata_t savedata;
UINT8 *save_p;

View file

@ -84,6 +84,7 @@
// SRB2Kart
#include "k_kart.h"
#include "k_pwrlv.h"
//
// Map MD5, calculated on level load.

View file

@ -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<<FRACBITS)/10);
encore = M_RandomChance(FRACUNIT>>2);
break;
case 1:
hardmode = M_RandomChance((3<<FRACBITS)/10);
encore = false;
break;
case 0:
default:
hardmode = encore = false;
break;
}
if (cv_speedscramble.value)
speedscramble = (hardmode ? 2 : 1);
else
speedscramble = -1;
if (cv_encorescramble.value)
encorescramble = (encore ? 1 : 0);
else
encorescramble = -1;
}
K_SetPowerLevelScrambles(powertype);
if (!multiplayer)
{
@ -1157,7 +1079,7 @@ void Y_StartIntermission(void)
}
if (powertype != -1)
Y_UpdatePowerLevels();
K_UpdatePowerLevels();
//if (intertype == int_race || intertype == int_match)
{