mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Lap based power level
This commit is contained in:
parent
f54eaee9af
commit
ebb34ff9d4
22 changed files with 415 additions and 317 deletions
|
|
@ -1641,34 +1641,14 @@ void CV_SaveVars(UINT8 **p, boolean in_demo)
|
|||
// the client will reset all netvars to default before loading
|
||||
WRITEUINT16(*p, 0x0000);
|
||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||
if (((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar)) || (in_demo && cvar->netid == cv_numlaps.netid))
|
||||
if ((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar))
|
||||
{
|
||||
if (in_demo)
|
||||
WRITESTRING(*p, cvar->name);
|
||||
else
|
||||
WRITEUINT16(*p, cvar->netid);
|
||||
|
||||
// UGLY HACK: Save proper lap count in net replays
|
||||
if (in_demo && cvar->netid == cv_numlaps.netid)
|
||||
{
|
||||
if (cv_basenumlaps.value &&
|
||||
(!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
||||
|| (mapheaderinfo[gamemap - 1]->numlaps > cv_basenumlaps.value))
|
||||
)
|
||||
{
|
||||
WRITESTRING(*p, cv_basenumlaps.string);
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[9];
|
||||
sprintf(buf, "%d", mapheaderinfo[gamemap - 1]->numlaps);
|
||||
WRITESTRING(*p, buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITESTRING(*p, cvar->string);
|
||||
}
|
||||
WRITESTRING(*p, cvar->string);
|
||||
|
||||
WRITEUINT8(*p, false);
|
||||
++count;
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ static void Got_DiscordInfo(UINT8 **cp, INT32 playernum);
|
|||
static void PointLimit_OnChange(void);
|
||||
static void TimeLimit_OnChange(void);
|
||||
static void NumLaps_OnChange(void);
|
||||
static void BaseNumLaps_OnChange(void);
|
||||
static void Mute_OnChange(void);
|
||||
|
||||
static void AutoBalance_OnChange(void);
|
||||
|
|
@ -141,7 +140,6 @@ static void Color4_OnChange(void);
|
|||
static void DummyConsvar_OnChange(void);
|
||||
static void SoundTest_OnChange(void);
|
||||
|
||||
static void BaseNumLaps_OnChange(void);
|
||||
static void KartFrantic_OnChange(void);
|
||||
static void KartSpeed_OnChange(void);
|
||||
static void KartEncore_OnChange(void);
|
||||
|
|
@ -467,10 +465,9 @@ static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"},
|
|||
consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange);
|
||||
static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}};
|
||||
consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange);
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_numlaps = CVAR_INIT ("numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange);
|
||||
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, "Map default"}, {0, NULL}};
|
||||
consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange);
|
||||
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {MAX_LAPS, "MAX"}, {0, "Map default"}, {0, NULL}};
|
||||
consvar_t cv_numlaps = CVAR_INIT ("numlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, numlaps_cons_t, NumLaps_OnChange);
|
||||
|
||||
// Point and time limits for every gametype
|
||||
INT32 pointlimits[NUMGAMETYPES];
|
||||
|
|
@ -691,7 +688,6 @@ void D_RegisterServerCommands(void)
|
|||
// misc
|
||||
CV_RegisterVar(&cv_pointlimit);
|
||||
CV_RegisterVar(&cv_numlaps);
|
||||
CV_RegisterVar(&cv_basenumlaps);
|
||||
|
||||
CV_RegisterVar(&cv_autobalance);
|
||||
CV_RegisterVar(&cv_teamscramble);
|
||||
|
|
@ -4480,24 +4476,6 @@ static void PointLimit_OnChange(void)
|
|||
CONS_Printf(M_GetText("Point limit disabled\n"));
|
||||
}
|
||||
|
||||
static void NumLaps_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
||||
&& (cv_numlaps.value > mapheaderinfo[gamemap - 1]->numlaps))
|
||||
{
|
||||
CV_StealthSetValue(&cv_numlaps, mapheaderinfo[gamemap - 1]->numlaps);
|
||||
}
|
||||
|
||||
// Just don't be verbose
|
||||
if (gametyperules & GTR_CIRCUIT)
|
||||
CONS_Printf(M_GetText("Number of laps set to %d\n"), cv_numlaps.value);
|
||||
}
|
||||
|
||||
static void NetTimeout_OnChange(void)
|
||||
{
|
||||
connectiontimeout = (tic_t)cv_nettimeout.value;
|
||||
|
|
@ -5759,22 +5737,24 @@ static void Command_ShowTime_f(void)
|
|||
}
|
||||
|
||||
// SRB2Kart: On change messages
|
||||
static void BaseNumLaps_OnChange(void)
|
||||
static void NumLaps_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == true)
|
||||
if (K_CanChangeRules() == false)
|
||||
{
|
||||
const char *str = va("%d", cv_basenumlaps.value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cv_basenumlaps.value == 0)
|
||||
{
|
||||
str = "map defaults";
|
||||
}
|
||||
|
||||
CONS_Printf(M_GetText("Number of laps will be changed to %s next round.\n"), str);
|
||||
if (leveltime < starttime)
|
||||
{
|
||||
CONS_Printf(M_GetText("Number of laps have been set to %d.\n"), cv_numlaps.value);
|
||||
numlaps = (UINT8)cv_numlaps.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Number of laps will be set to %d next round.\n"), cv_numlaps.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void KartFrantic_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ extern consvar_t cv_itemrespawn;
|
|||
extern consvar_t cv_pointlimit;
|
||||
extern consvar_t cv_timelimit;
|
||||
extern consvar_t cv_numlaps;
|
||||
extern consvar_t cv_basenumlaps;
|
||||
extern UINT32 timelimitintics;
|
||||
extern consvar_t cv_allowexitlevel;
|
||||
|
||||
|
|
|
|||
|
|
@ -537,6 +537,7 @@ typedef struct player_s
|
|||
INT16 totalring; // Total number of rings obtained for GP
|
||||
tic_t realtime; // integer replacement for leveltime
|
||||
UINT8 laps; // Number of laps (optional)
|
||||
UINT8 latestlap;
|
||||
INT32 starpostnum; // The number of the last starpost you hit
|
||||
|
||||
UINT8 ctfteam; // 0 == Spectator, 1 == Red, 2 == Blue
|
||||
|
|
|
|||
|
|
@ -700,6 +700,7 @@ extern INT16 scramblecount; //for CTF team scramble
|
|||
extern INT32 cheats;
|
||||
|
||||
// SRB2kart
|
||||
extern UINT8 numlaps;
|
||||
extern UINT8 gamespeed;
|
||||
extern boolean franticitems;
|
||||
extern boolean encoremode, prevencoremode;
|
||||
|
|
|
|||
17
src/g_demo.c
17
src/g_demo.c
|
|
@ -1999,6 +1999,7 @@ void G_BeginRecording(void)
|
|||
|
||||
WRITEUINT8(demo_p, demoflags);
|
||||
WRITEUINT8(demo_p, gametype & 0xFF);
|
||||
WRITEUINT8(demo_p, numlaps);
|
||||
|
||||
// file list
|
||||
m = demo_p;/* file count */
|
||||
|
|
@ -2429,6 +2430,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
|||
p += 16; // map md5
|
||||
flags = READUINT8(p); // demoflags
|
||||
p++; // gametype
|
||||
p++; // numlaps
|
||||
G_SkipDemoExtraFiles(&p);
|
||||
|
||||
aflags = flags & (DF_TIMEATTACK|DF_BREAKTHECAPSULES);
|
||||
|
|
@ -2486,6 +2488,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
|||
p += 16; // mapmd5
|
||||
flags = READUINT8(p);
|
||||
p++; // gametype
|
||||
p++; // numlaps
|
||||
G_SkipDemoExtraFiles(&p);
|
||||
if (!(flags & aflags))
|
||||
{
|
||||
|
|
@ -2600,6 +2603,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
|||
}
|
||||
|
||||
pdemo->gametype = READUINT8(info_p);
|
||||
pdemo->numlaps = READUINT8(info_p);
|
||||
|
||||
pdemo->addonstatus = G_CheckDemoExtraFiles(&info_p, true);
|
||||
info_p += 4; // RNG seed
|
||||
|
|
@ -2626,20 +2630,11 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
|||
if (!stricmp(kartspeed_cons_t[j].strvalue, svalue))
|
||||
pdemo->kartspeed = kartspeed_cons_t[j].value;
|
||||
}
|
||||
else if (netid == cv_basenumlaps.netid && pdemo->gametype == GT_RACE)
|
||||
pdemo->numlaps = atoi(svalue);
|
||||
}
|
||||
|
||||
if (pdemoflags & DF_ENCORE)
|
||||
pdemo->kartspeed |= DF_ENCORE;
|
||||
|
||||
/*// Temporary info until this is actually present in replays.
|
||||
(void)extrainfo_p;
|
||||
sprintf(pdemo->winnername, "transrights420");
|
||||
pdemo->winnerskin = 1;
|
||||
pdemo->winnercolor = SKINCOLOR_MOONSET;
|
||||
pdemo->winnertime = 6666;*/
|
||||
|
||||
// Read standings!
|
||||
count = 0;
|
||||
|
||||
|
|
@ -2835,6 +2830,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
demoflags = READUINT8(demo_p);
|
||||
gametype = READUINT8(demo_p);
|
||||
G_SetGametype(gametype);
|
||||
numlaps = READUINT8(demo_p);
|
||||
|
||||
if (demo.title) // Titledemos should always play and ought to always be compatible with whatever wadlist is running.
|
||||
G_SkipDemoExtraFiles(&demo_p);
|
||||
|
|
@ -3258,6 +3254,7 @@ void G_AddGhost(char *defdemoname)
|
|||
}
|
||||
|
||||
p++; // gametype
|
||||
p++; // numlaps
|
||||
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
|
||||
|
||||
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||
|
|
@ -3475,7 +3472,7 @@ void G_UpdateStaffGhostName(lumpnum_t l)
|
|||
}
|
||||
|
||||
p++; // Gametype
|
||||
|
||||
p++; // numlaps
|
||||
G_SkipDemoExtraFiles(&p);
|
||||
|
||||
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||
|
|
|
|||
|
|
@ -303,6 +303,7 @@ INT32 cheats; //for multiplayer cheat commands
|
|||
|
||||
// SRB2Kart
|
||||
// Cvars that we don't want changed mid-game
|
||||
UINT8 numlaps; // Removed from Cvar hell
|
||||
UINT8 gamespeed; // Game's current speed (or difficulty, or cc, or etc); 0 for easy, 1 for normal, 2 for hard
|
||||
boolean encoremode = false; // Encore Mode currently enabled?
|
||||
boolean prevencoremode;
|
||||
|
|
@ -2198,6 +2199,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
INT32 khudcardanimation;
|
||||
INT16 totalring;
|
||||
UINT8 laps;
|
||||
UINT8 latestlap;
|
||||
UINT16 skincolor;
|
||||
INT32 skin;
|
||||
UINT32 availabilities;
|
||||
|
|
@ -2284,6 +2286,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
khudfault = 0;
|
||||
nocontrol = 0;
|
||||
laps = 0;
|
||||
latestlap = 0;
|
||||
totalring = 0;
|
||||
roundscore = 0;
|
||||
exiting = 0;
|
||||
|
|
@ -2324,6 +2327,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
nocontrol = players[player].nocontrol;
|
||||
|
||||
laps = players[player].laps;
|
||||
latestlap = players[player].latestlap;
|
||||
|
||||
totalring = players[player].totalring;
|
||||
roundscore = players[player].roundscore;
|
||||
|
||||
|
|
@ -2380,6 +2385,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->karthud[khud_cardanimation] = khudcardanimation;
|
||||
|
||||
p->laps = laps;
|
||||
p->latestlap = latestlap;
|
||||
p->totalring = totalring;
|
||||
|
||||
p->bot = bot;
|
||||
|
|
|
|||
|
|
@ -2421,7 +2421,7 @@ static void HU_DrawRankings(void)
|
|||
if (circuitmap)
|
||||
{
|
||||
V_DrawCenteredString(64, 8, 0, "LAP COUNT");
|
||||
V_DrawCenteredString(64, 16, hilicol, va("%d", cv_numlaps.value));
|
||||
V_DrawCenteredString(64, 16, hilicol, va("%d", numlaps));
|
||||
}
|
||||
|
||||
V_DrawCenteredString(256, 8, 0, "GAME SPEED");
|
||||
|
|
|
|||
14
src/k_hud.c
14
src/k_hud.c
|
|
@ -1706,7 +1706,7 @@ static void K_DrawKartPositionNum(INT32 num)
|
|||
{
|
||||
localpatch = kp_winnernum[(leveltime % (NUMWINFRAMES*3)) / 3];
|
||||
}
|
||||
else if (stplyr->laps >= cv_numlaps.value || stplyr->exiting) // Check for the final lap, or won
|
||||
else if (stplyr->laps >= numlaps || stplyr->exiting) // Check for the final lap, or won
|
||||
{
|
||||
boolean useRedNums = K_IsPlayerLosing(stplyr);
|
||||
|
||||
|
|
@ -2337,7 +2337,7 @@ static void K_drawKartLapsAndRings(void)
|
|||
V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_splitlapflag);
|
||||
V_DrawScaledPatch(fx+22, fy, V_HUDTRANS|V_SLIDEIN|splitflags, frameslash);
|
||||
|
||||
if (cv_numlaps.value >= 10)
|
||||
if (numlaps >= 10)
|
||||
{
|
||||
UINT8 ln[2];
|
||||
ln[0] = ((stplyr->laps / 10) % 10);
|
||||
|
|
@ -2346,8 +2346,8 @@ static void K_drawKartLapsAndRings(void)
|
|||
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
|
||||
V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
|
||||
|
||||
ln[0] = ((abs(cv_numlaps.value) / 10) % 10);
|
||||
ln[1] = (abs(cv_numlaps.value) % 10);
|
||||
ln[0] = ((abs(numlaps) / 10) % 10);
|
||||
ln[1] = (abs(numlaps) % 10);
|
||||
|
||||
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
|
||||
V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
|
||||
|
|
@ -2355,7 +2355,7 @@ static void K_drawKartLapsAndRings(void)
|
|||
else
|
||||
{
|
||||
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->laps) % 10]);
|
||||
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(cv_numlaps.value) % 10]);
|
||||
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(numlaps) % 10]);
|
||||
}
|
||||
|
||||
// Rings
|
||||
|
|
@ -2393,7 +2393,7 @@ static void K_drawKartLapsAndRings(void)
|
|||
{
|
||||
// Laps
|
||||
V_DrawScaledPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_lapsticker);
|
||||
V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", min(stplyr->laps, cv_numlaps.value), cv_numlaps.value));
|
||||
V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", min(stplyr->laps, numlaps), numlaps));
|
||||
|
||||
// Rings
|
||||
if (!uselives)
|
||||
|
|
@ -4367,7 +4367,7 @@ static void K_drawLapStartAnim(void)
|
|||
kp_lapanim_hand[stplyr->karthud[khud_laphand]-1], NULL);
|
||||
}
|
||||
|
||||
if (stplyr->laps == (UINT8)(cv_numlaps.value))
|
||||
if (stplyr->laps == (UINT8)(numlaps))
|
||||
{
|
||||
newval = (62 - (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (62 - (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
|
|
|
|||
|
|
@ -8261,7 +8261,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
|||
// distance calculation to work easily
|
||||
if ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) == 0U)
|
||||
{
|
||||
const UINT8 numfulllapsleft = ((UINT8)cv_numlaps.value - player->laps);
|
||||
const UINT8 numfulllapsleft = ((UINT8)numlaps - player->laps);
|
||||
|
||||
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
|
||||
|
||||
|
|
|
|||
291
src/k_pwrlv.c
291
src/k_pwrlv.c
|
|
@ -1,5 +1,12 @@
|
|||
/// \file k_pwrlv.c
|
||||
/// \brief SRB2Kart Power Levels
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2018-2022 by Sally Cochenour
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
// \brief Power Level system
|
||||
|
||||
#include "k_pwrlv.h"
|
||||
#include "d_netcmd.h"
|
||||
|
|
@ -19,9 +26,12 @@ UINT16 vspowerlevel[PWRLV_NUMTYPES];
|
|||
// 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];
|
||||
// Total calculated power add during the match,
|
||||
// totalled at the end of the round.
|
||||
INT16 clientPowerAdd[MAXPLAYERS];
|
||||
|
||||
// Players who spectated mid-race
|
||||
UINT8 spectateGriefed = 0;
|
||||
|
||||
// Game setting scrambles based on server Power Level
|
||||
SINT8 speedscramble = -1;
|
||||
|
|
@ -52,8 +62,14 @@ void K_ClearClientPowerLevels(void)
|
|||
{
|
||||
UINT8 i, j;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
clientPowerAdd[i] = 0;
|
||||
|
||||
for (j = 0; j < PWRLV_NUMTYPES; j++)
|
||||
{
|
||||
clientpowerlevels[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from this: http://wiki.tockdom.com/wiki/Player_Rating
|
||||
|
|
@ -143,7 +159,206 @@ INT16 K_CalculatePowerLevelAvg(void)
|
|||
return (INT16)(avg >> FRACBITS);
|
||||
}
|
||||
|
||||
// -- K_UpdatePowerLevels could not be moved here due to usage of y_data, unfortunately. --
|
||||
void K_UpdatePowerLevels(player_t *player)
|
||||
{
|
||||
const UINT8 playerNum = player - players;
|
||||
const boolean exitBonus = ((player->laps > numlaps) || (player->pflags & PF_NOCONTEST));
|
||||
|
||||
SINT8 powerType = K_UsingPowerLevels();
|
||||
|
||||
INT16 yourScore = 0;
|
||||
UINT16 yourPower = 0;
|
||||
|
||||
UINT8 i;
|
||||
|
||||
// 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.
|
||||
|
||||
if (powerType == PWRLV_DISABLED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playeringame[playerNum] || player->spectator)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CONS_Printf("Power Level Gain for player %d:\n", playerNum);
|
||||
|
||||
yourPower = clientpowerlevels[playerNum][powerType];
|
||||
if (yourPower == 0)
|
||||
{
|
||||
// Guests don't record power level changes.
|
||||
return;
|
||||
}
|
||||
|
||||
CONS_Printf("Player %d's PWR.LV: %d\n", playerNum, yourPower);
|
||||
|
||||
if (gametyperules & GTR_CIRCUIT)
|
||||
{
|
||||
yourScore = MAXPLAYERS - player->position;
|
||||
}
|
||||
else
|
||||
{
|
||||
yourScore = player->score;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
UINT16 theirScore = 0;
|
||||
INT16 theirPower = PWRLVRECORD_DEF;
|
||||
|
||||
INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV
|
||||
INT16 inc = 0; // Total pt increment
|
||||
|
||||
boolean won = false;
|
||||
|
||||
if (i == playerNum) // Same person
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CONS_Printf("Player %d VS Player %d:\n", playerNum, i);
|
||||
|
||||
theirPower = clientpowerlevels[i][powerType];
|
||||
if (theirPower == 0)
|
||||
{
|
||||
// No power level (splitscreen guests, bots)
|
||||
continue;
|
||||
}
|
||||
|
||||
CONS_Printf("Player %d's PWR.LV: %d\n", i, theirPower);
|
||||
|
||||
if (gametyperules & GTR_CIRCUIT)
|
||||
{
|
||||
theirScore = MAXPLAYERS - players[i].position;
|
||||
}
|
||||
else
|
||||
{
|
||||
theirScore = players[i].score;
|
||||
}
|
||||
|
||||
if (yourScore == theirScore) // Tie -- neither get any points for this match up.
|
||||
{
|
||||
CONS_Printf("TIE, no change.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
won = (yourScore > theirScore);
|
||||
|
||||
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 (exitBonus == false)
|
||||
{
|
||||
CONS_Printf("Reduced (%d / %d = %d) because it's not the end of the race\n", inc, numlaps, inc/numlaps);
|
||||
inc /= numlaps;
|
||||
}
|
||||
|
||||
if (inc == 0)
|
||||
{
|
||||
CONS_Printf("Total Result: No increment, no change.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
CONS_Printf("Total Result: Increment of %d.\n", inc);
|
||||
|
||||
clientPowerAdd[playerNum] += inc;
|
||||
clientPowerAdd[i] -= inc;
|
||||
}
|
||||
}
|
||||
|
||||
INT16 K_FinalPowerIncrement(player_t *player, INT16 yourPower, INT16 increment)
|
||||
{
|
||||
INT16 inc = increment;
|
||||
UINT8 numPlayers = 0;
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
numPlayers++;
|
||||
}
|
||||
|
||||
if (inc <= 0)
|
||||
{
|
||||
if (player->position == 1)
|
||||
{
|
||||
// Won the whole match?
|
||||
// Get at least one point.
|
||||
inc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// You trade points in 1v1s,
|
||||
// but is more lenient in bigger lobbies.
|
||||
inc /= max(1, numPlayers-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (yourPower + inc > PWRLVRECORD_MAX)
|
||||
{
|
||||
inc -= ((yourPower + inc) - PWRLVRECORD_MAX);
|
||||
}
|
||||
|
||||
if (yourPower + inc < PWRLVRECORD_MIN)
|
||||
{
|
||||
inc -= ((yourPower + inc) - PWRLVRECORD_MIN);
|
||||
}
|
||||
|
||||
return inc;
|
||||
}
|
||||
|
||||
void K_CashInPowerLevels(void)
|
||||
{
|
||||
SINT8 powerType = K_UsingPowerLevels();
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (powerType != PWRLV_DISABLED)
|
||||
{
|
||||
INT16 inc = K_FinalPowerIncrement(&players[i], clientpowerlevels[i][powerType], clientPowerAdd[i]);
|
||||
clientpowerlevels[i][powerType] += inc;
|
||||
|
||||
if (!demo.playback && i == consoleplayer)
|
||||
{
|
||||
vspowerlevel[powerType] = clientpowerlevels[i][powerType];
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
{
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
}
|
||||
|
||||
G_SaveGameData();
|
||||
}
|
||||
}
|
||||
|
||||
clientPowerAdd[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void K_SetPowerLevelScrambles(SINT8 powertype)
|
||||
{
|
||||
|
|
@ -227,7 +442,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype)
|
|||
{
|
||||
case 5:
|
||||
speed = KARTSPEED_HARD;
|
||||
encore = true;
|
||||
encore = P_RandomChance(FRACUNIT>>1);
|
||||
break;
|
||||
case 4:
|
||||
speed = P_RandomChance((7<<FRACBITS)/10) ? KARTSPEED_HARD : KARTSPEED_NORMAL;
|
||||
|
|
@ -238,7 +453,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype)
|
|||
encore = P_RandomChance(FRACUNIT>>2);
|
||||
break;
|
||||
case 2:
|
||||
speed = 1;
|
||||
speed = KARTSPEED_NORMAL;
|
||||
encore = P_RandomChance(FRACUNIT>>3);
|
||||
break;
|
||||
case 1: default:
|
||||
|
|
@ -254,7 +469,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype)
|
|||
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)
|
||||
if (cv_kartspeed.value == KARTSPEED_AUTO)
|
||||
speedscramble = speed;
|
||||
else
|
||||
speedscramble = -1;
|
||||
|
|
@ -278,16 +493,13 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss)
|
|||
UINT16 theirpower = PWRLVRECORD_DEF;
|
||||
INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV
|
||||
INT16 inc = 0;
|
||||
UINT8 lapsLeft = 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;
|
||||
|
|
@ -296,14 +508,25 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss)
|
|||
if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE))
|
||||
return;
|
||||
|
||||
spectateGriefed++;
|
||||
|
||||
// This server isn't using power levels, so don't mess with them.
|
||||
if (!cv_kartusepwrlv.value)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator)
|
||||
if ((playeringame[i] && !players[i].spectator)
|
||||
|| (i == playernum))
|
||||
{
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (p < 2) // no players
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((gametyperules & GTR_CIRCUIT))
|
||||
powertype = PWRLV_RACE;
|
||||
|
|
@ -317,14 +540,12 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss)
|
|||
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;
|
||||
lapsLeft = (numlaps - players[playernum].latestlap);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
INT16 thisInc = 0;
|
||||
|
||||
if (i == playernum)
|
||||
continue;
|
||||
|
||||
|
|
@ -334,24 +555,40 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss)
|
|||
theirpower = clientpowerlevels[i][powertype];
|
||||
|
||||
diff = yourpower - theirpower;
|
||||
inc -= K_CalculatePowerLevelInc(diff);
|
||||
thisInc = K_CalculatePowerLevelInc(diff);
|
||||
|
||||
if (thisInc == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
thisInc *= lapsLeft;
|
||||
clientPowerAdd[i] += thisInc;
|
||||
inc -= thisInc;
|
||||
}
|
||||
|
||||
if (inc == 0) // No change.
|
||||
if (inc >= 0)
|
||||
{
|
||||
// No change. Also don't award points.
|
||||
return;
|
||||
}
|
||||
|
||||
if (yourpower + inc > PWRLVRECORD_MAX) // I mean... we're subtracting... but y'know how it is :V
|
||||
if (yourpower + inc > PWRLVRECORD_MAX) // I mean... we're always 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 (!demo.playback && playernum == consoleplayer)
|
||||
// pointloss isn't set for stuff like sync-outs,
|
||||
// which shouldn't be so harsh on the victim!
|
||||
if (!demo.playback && pointloss == true && playernum == consoleplayer)
|
||||
{
|
||||
vspowerlevel[powertype] = clientpowerlevels[playernum][powertype];
|
||||
vspowerlevel[powertype] = clientpowerlevels[playernum][powertype] + inc;
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
{
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
G_SaveGameData(); // save your punishment!
|
||||
}
|
||||
|
||||
G_SaveGameData();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,27 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2018-2022 by Sally Cochenour
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
// \brief Power Level system
|
||||
|
||||
#ifndef __K_PWRLV__
|
||||
#define __K_PWRLV__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "doomdef.h"
|
||||
#include "d_player.h"
|
||||
|
||||
#define PWRLV_DISABLED -1
|
||||
#define PWRLV_RACE 0
|
||||
#define PWRLV_BATTLE 1
|
||||
#define PWRLV_NUMTYPES 2
|
||||
typedef enum
|
||||
{
|
||||
PWRLV_DISABLED = -1,
|
||||
PWRLV_RACE = 0,
|
||||
PWRLV_BATTLE = 1,
|
||||
PWRLV_NUMTYPES = 2,
|
||||
} pwrlv_type_t;
|
||||
|
||||
#define PWRLVRECORD_START 1000
|
||||
#define PWRLVRECORD_DEF 5000
|
||||
|
|
@ -19,13 +33,16 @@ extern SINT8 encorescramble;
|
|||
|
||||
extern UINT16 vspowerlevel[PWRLV_NUMTYPES];
|
||||
extern UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES];
|
||||
extern INT16 nospectategrief[MAXPLAYERS];
|
||||
extern INT16 clientPowerAdd[MAXPLAYERS];
|
||||
extern UINT8 spectateGriefed;
|
||||
|
||||
SINT8 K_UsingPowerLevels(void);
|
||||
void K_ClearClientPowerLevels(void);
|
||||
INT16 K_CalculatePowerLevelInc(INT16 diff);
|
||||
INT16 K_CalculatePowerLevelAvg(void);
|
||||
//void K_UpdatePowerLevels(void);
|
||||
void K_UpdatePowerLevels(player_t *player);
|
||||
INT16 K_FinalPowerIncrement(player_t *player, INT16 yourPower, INT16 increment);
|
||||
void K_CashInPowerLevels(void);
|
||||
void K_SetPowerLevelScrambles(SINT8 powertype);
|
||||
void K_PlayerForfeit(UINT8 playernum, boolean nopointloss);
|
||||
|
||||
|
|
|
|||
|
|
@ -446,6 +446,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->realtime);
|
||||
else if (fastcmp(field,"laps"))
|
||||
lua_pushinteger(L, plr->laps);
|
||||
else if (fastcmp(field,"latestlap"))
|
||||
lua_pushinteger(L, plr->latestlap);
|
||||
else if (fastcmp(field,"ctfteam"))
|
||||
lua_pushinteger(L, plr->ctfteam);
|
||||
else if (fastcmp(field,"checkskip"))
|
||||
|
|
@ -786,6 +788,8 @@ static int player_set(lua_State *L)
|
|||
plr->realtime = (tic_t)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"laps"))
|
||||
plr->laps = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"latestlap"))
|
||||
plr->latestlap = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"ctfteam"))
|
||||
plr->ctfteam = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"checkskip"))
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
lua_pushinteger(L, mapobjectscale);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"numlaps")) {
|
||||
lua_pushinteger(L, cv_numlaps.value);
|
||||
lua_pushinteger(L, numlaps);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"racecountdown")) {
|
||||
lua_pushinteger(L, racecountdown);
|
||||
|
|
|
|||
10
src/m_menu.c
10
src/m_menu.c
|
|
@ -1478,17 +1478,17 @@ static menuitem_t OP_GameOptionsMenu[] =
|
|||
{IT_STRING | IT_SUBMENU, NULL, "Random Item Toggles...", {.submenu = &OP_MonitorToggleDef}, 10},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Game Speed", {.cvar = &cv_kartspeed}, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Frantic Items", {.cvar = &cv_kartfrantic}, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Frantic Items", {.cvar = &cv_kartfrantic}, 40},
|
||||
{IT_SECRET, NULL, "Encore Mode", {.cvar = &cv_kartencore}, 50},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Number of Laps", {.cvar = &cv_basenumlaps}, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Number of Laps", {.cvar = &cv_numlaps}, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Exit Countdown Timer", {.cvar = &cv_countdowntime}, 80},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Time Limit", {.cvar = &cv_timelimit}, 100},
|
||||
{IT_STRING | IT_CVAR, NULL, "Starting Bumpers", {.cvar = &cv_kartbumpers}, 110},
|
||||
{IT_STRING | IT_CVAR, NULL, "Karma Comeback", {.cvar = &cv_kartcomeback}, 120},
|
||||
{IT_STRING | IT_CVAR, NULL, "Starting Bumpers", {.cvar = &cv_kartbumpers}, 110},
|
||||
{IT_STRING | IT_CVAR, NULL, "Karma Comeback", {.cvar = &cv_kartcomeback}, 120},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Track Power Levels", {.cvar = &cv_kartusepwrlv}, 140},
|
||||
{IT_STRING | IT_CVAR, NULL, "Track Power Levels", {.cvar = &cv_kartusepwrlv}, 140},
|
||||
};
|
||||
|
||||
static menuitem_t OP_ServerOptionsMenu[] =
|
||||
|
|
|
|||
|
|
@ -792,16 +792,11 @@ boolean P_CheckRacers(void)
|
|||
boolean eliminatelast = cv_karteliminatelast.value;
|
||||
boolean everyonedone = true;
|
||||
boolean eliminatebots = false;
|
||||
boolean griefed = false;
|
||||
const boolean griefed = (spectateGriefed > 0);
|
||||
|
||||
// Check if all the players in the race have finished. If so, end the level.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (nospectategrief[i] != -1) // prevent spectate griefing
|
||||
{
|
||||
griefed = true;
|
||||
}
|
||||
|
||||
if (!playeringame[i] || players[i].spectator || players[i].lives <= 0) // Not playing
|
||||
{
|
||||
// Y'all aren't even playing
|
||||
|
|
@ -922,7 +917,7 @@ boolean P_CheckRacers(void)
|
|||
// We're still playing, but no one else is, so we need to reset spectator griefing.
|
||||
if (numplayersingame <= 1)
|
||||
{
|
||||
memset(nospectategrief, -1, sizeof (nospectategrief));
|
||||
spectateGriefed = 0;
|
||||
}
|
||||
|
||||
// Turns out we're still having a good time & playing the game, we didn't have to do anything :)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@
|
|||
|
||||
//#define VIEWHEIGHTS "41"
|
||||
|
||||
// Maximum laps per map.
|
||||
#define MAX_LAPS 99
|
||||
|
||||
// Maximum player score.
|
||||
#define MAXSCORE 99999990 // 999999990
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ static void P_NetArchivePlayers(void)
|
|||
{
|
||||
WRITEINT16(save_p, clientpowerlevels[i][j]);
|
||||
}
|
||||
WRITEINT16(save_p, clientPowerAdd[i]);
|
||||
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
|
@ -167,6 +168,7 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEINT16(save_p, players[i].totalring);
|
||||
WRITEUINT32(save_p, players[i].realtime);
|
||||
WRITEUINT8(save_p, players[i].laps);
|
||||
WRITEUINT8(save_p, players[i].latestlap);
|
||||
WRITEINT32(save_p, players[i].starpostnum);
|
||||
|
||||
WRITEUINT8(save_p, players[i].ctfteam);
|
||||
|
|
@ -404,6 +406,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
{
|
||||
clientpowerlevels[i][j] = READINT16(save_p);
|
||||
}
|
||||
clientPowerAdd[i] = READINT16(save_p);
|
||||
|
||||
// Do NOT memset player struct to 0
|
||||
// other areas may initialize data elsewhere
|
||||
|
|
@ -466,6 +469,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].totalring = READINT16(save_p); // Total number of rings obtained for GP
|
||||
players[i].realtime = READUINT32(save_p); // integer replacement for leveltime
|
||||
players[i].laps = READUINT8(save_p); // Number of laps (optional)
|
||||
players[i].latestlap = READUINT8(save_p);
|
||||
players[i].starpostnum = READINT32(save_p);
|
||||
|
||||
players[i].ctfteam = READUINT8(save_p); // 1 == Red, 2 == Blue
|
||||
|
|
@ -4495,6 +4499,7 @@ static void P_NetArchiveMisc(boolean resending)
|
|||
WRITEUINT8(save_p, battlecapsules);
|
||||
|
||||
WRITEUINT8(save_p, gamespeed);
|
||||
WRITEUINT8(save_p, numlaps);
|
||||
WRITEUINT8(save_p, franticitems);
|
||||
WRITEUINT8(save_p, comeback);
|
||||
|
||||
|
|
@ -4515,8 +4520,7 @@ static void P_NetArchiveMisc(boolean resending)
|
|||
WRITEUINT32(save_p, indirectitemcooldown);
|
||||
WRITEUINT32(save_p, mapreset);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
WRITEINT16(save_p, nospectategrief[i]);
|
||||
WRITEUINT8(save_p, spectateGriefed);
|
||||
|
||||
WRITEUINT8(save_p, thwompsactive);
|
||||
WRITEUINT8(save_p, lastLowestLap);
|
||||
|
|
@ -4644,6 +4648,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
|||
battlecapsules = (boolean)READUINT8(save_p);
|
||||
|
||||
gamespeed = READUINT8(save_p);
|
||||
numlaps = READUINT8(save_p);
|
||||
franticitems = (boolean)READUINT8(save_p);
|
||||
comeback = (boolean)READUINT8(save_p);
|
||||
|
||||
|
|
@ -4664,8 +4669,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
|||
indirectitemcooldown = READUINT32(save_p);
|
||||
mapreset = READUINT32(save_p);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
nospectategrief[i] = READINT16(save_p);
|
||||
spectateGriefed = READUINT8(save_p);
|
||||
|
||||
thwompsactive = (boolean)READUINT8(save_p);
|
||||
lastLowestLap = READUINT8(save_p);
|
||||
|
|
|
|||
|
|
@ -4063,25 +4063,37 @@ static void P_InitPlayers(void)
|
|||
|
||||
static void P_InitGametype(void)
|
||||
{
|
||||
spectateGriefed = 0;
|
||||
K_CashInPowerLevels(); // Pushes power level changes even if intermission was skipped
|
||||
|
||||
P_InitPlayers();
|
||||
|
||||
if (modeattacking && !demo.playback)
|
||||
P_LoadRecordGhosts();
|
||||
|
||||
if ((gametyperules & GTR_CIRCUIT) && server)
|
||||
numlaps = 0;
|
||||
if (gametyperules & GTR_CIRCUIT)
|
||||
{
|
||||
if ((netgame || multiplayer) && cv_basenumlaps.value
|
||||
if ((netgame || multiplayer) && cv_numlaps.value
|
||||
&& (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
||||
|| (mapheaderinfo[gamemap - 1]->numlaps > cv_basenumlaps.value)))
|
||||
|| (mapheaderinfo[gamemap - 1]->numlaps > cv_numlaps.value)))
|
||||
{
|
||||
CV_StealthSetValue(&cv_numlaps, cv_basenumlaps.value);
|
||||
numlaps = cv_numlaps.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_StealthSetValue(&cv_numlaps, mapheaderinfo[gamemap - 1]->numlaps);
|
||||
numlaps = mapheaderinfo[gamemap - 1]->numlaps;
|
||||
}
|
||||
}
|
||||
|
||||
wantedcalcdelay = wantedfrequency*2;
|
||||
indirectitemcooldown = 0;
|
||||
mapreset = 0;
|
||||
|
||||
thwompsactive = false;
|
||||
lastLowestLap = 0;
|
||||
spbplace = -1;
|
||||
|
||||
// Start recording replay in multiplayer with a temp filename
|
||||
//@TODO I'd like to fix dedis crashing when recording replays for the future too...
|
||||
if (!demo.playback && multiplayer && !dedicated)
|
||||
|
|
@ -4117,6 +4129,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
// Map header should always be in place at this point
|
||||
INT32 i, ranspecialwipe = 0;
|
||||
sector_t *ss;
|
||||
|
||||
levelloading = true;
|
||||
|
||||
// This is needed. Don't touch.
|
||||
|
|
@ -4430,17 +4443,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
K_InitDirector();
|
||||
}
|
||||
|
||||
wantedcalcdelay = wantedfrequency*2;
|
||||
indirectitemcooldown = 0;
|
||||
mapreset = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
nospectategrief[i] = -1;
|
||||
|
||||
thwompsactive = false;
|
||||
lastLowestLap = 0;
|
||||
spbplace = -1;
|
||||
|
||||
// clear special respawning que
|
||||
iquehead = iquetail = 0;
|
||||
|
||||
|
|
|
|||
42
src/p_spec.c
42
src/p_spec.c
|
|
@ -1917,14 +1917,6 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
player->karthud[khud_laphand] = 0; // No hands in FREE PLAY
|
||||
|
||||
player->karthud[khud_lapanimation] = 80;
|
||||
|
||||
// save best lap for record attack
|
||||
if (player == &players[consoleplayer])
|
||||
{
|
||||
if (curlap < bestlap || bestlap == 0)
|
||||
bestlap = curlap;
|
||||
curlap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rainbowstartavailable == true)
|
||||
|
|
@ -1938,18 +1930,18 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
rainbowstartavailable = false;
|
||||
}
|
||||
|
||||
if (netgame && player->laps >= (UINT8)cv_numlaps.value)
|
||||
if (netgame && player->laps >= numlaps)
|
||||
CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players]));
|
||||
|
||||
player->starpostnum = 0;
|
||||
|
||||
if (P_IsDisplayPlayer(player))
|
||||
{
|
||||
if (player->laps == (UINT8)(cv_numlaps.value)) // final lap
|
||||
if (player->laps == numlaps) // final lap
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
else if ((player->laps > 1) && (player->laps < (UINT8)(cv_numlaps.value))) // non-final lap
|
||||
else if ((player->laps > 1) && (player->laps < numlaps)) // non-final lap
|
||||
S_StartSound(NULL, sfx_s221);
|
||||
else if (player->laps > (UINT8)(cv_numlaps.value))
|
||||
else if (player->laps > numlaps)
|
||||
{
|
||||
// finished
|
||||
S_StartSound(NULL, sfx_s3k6a);
|
||||
|
|
@ -1958,7 +1950,7 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((player->laps > (UINT8)(cv_numlaps.value)) && (player->position == 1))
|
||||
if ((player->laps > numlaps) && (player->position == 1))
|
||||
{
|
||||
// opponent finished
|
||||
S_StartSound(NULL, sfx_s253);
|
||||
|
|
@ -1966,12 +1958,34 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
}
|
||||
|
||||
// finished race exit setup
|
||||
if (player->laps > (unsigned)cv_numlaps.value)
|
||||
if (player->laps > numlaps)
|
||||
{
|
||||
P_DoPlayerExit(player);
|
||||
P_SetupSignExit(player);
|
||||
}
|
||||
|
||||
if (player->laps > player->latestlap)
|
||||
{
|
||||
if (player->laps > 1)
|
||||
{
|
||||
// save best lap for record attack
|
||||
if (modeattacking && player == &players[consoleplayer])
|
||||
{
|
||||
if (curlap < bestlap || bestlap == 0)
|
||||
{
|
||||
bestlap = curlap;
|
||||
}
|
||||
|
||||
curlap = 0;
|
||||
}
|
||||
|
||||
// Update power levels for this lap.
|
||||
K_UpdatePowerLevels(player);
|
||||
}
|
||||
|
||||
player->latestlap = player->laps;
|
||||
}
|
||||
|
||||
thwompsactive = true; // Lap 2 effects
|
||||
|
||||
lowestLap = P_FindLowestLap();
|
||||
|
|
|
|||
|
|
@ -873,7 +873,7 @@ void P_RestoreMusic(player_t *player)
|
|||
#if 0
|
||||
// Event - Final Lap
|
||||
// Still works for GME, but disabled for consistency
|
||||
if ((gametyperules & GTR_CIRCUIT) && player->laps >= (UINT8)(cv_numlaps.value))
|
||||
if ((gametyperules & GTR_CIRCUIT) && player->laps >= numlaps)
|
||||
S_SpeedMusic(1.2f);
|
||||
#endif
|
||||
if (mapmusresume && cv_resume.value)
|
||||
|
|
@ -3851,6 +3851,7 @@ void P_DoTimeOver(player_t *player)
|
|||
}
|
||||
|
||||
player->pflags |= PF_NOCONTEST;
|
||||
K_UpdatePowerLevels(player);
|
||||
|
||||
if (G_GametypeUsesLives())
|
||||
{
|
||||
|
|
|
|||
175
src/y_inter.c
175
src/y_inter.c
|
|
@ -214,7 +214,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
|||
{
|
||||
INT32 i, j;
|
||||
boolean completed[MAXPLAYERS];
|
||||
INT32 numplayersingame = 0, numgriefers = 0;
|
||||
INT32 numplayersingame = 0;
|
||||
|
||||
// Initialize variables
|
||||
if (rankingsmode > 1)
|
||||
|
|
@ -273,9 +273,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
|||
{
|
||||
data.val[i] = UINT32_MAX;
|
||||
|
||||
if (nospectategrief[i] != -1)
|
||||
numgriefers++;
|
||||
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
{
|
||||
data.increase[i] = INT16_MIN;
|
||||
|
|
@ -324,10 +321,10 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
|||
{
|
||||
if ((powertype == PWRLV_DISABLED)
|
||||
&& !(players[i].pflags & PF_NOCONTEST)
|
||||
&& (data.pos[data.numplayers] < (numplayersingame + numgriefers)))
|
||||
&& (data.pos[data.numplayers] < (numplayersingame + spectateGriefed)))
|
||||
{
|
||||
// Online rank is handled further below in this file.
|
||||
data.increase[i] = K_CalculateGPRankPoints(data.pos[data.numplayers], numplayersingame + numgriefers);
|
||||
data.increase[i] = K_CalculateGPRankPoints(data.pos[data.numplayers], numplayersingame + spectateGriefed);
|
||||
players[i].score += data.increase[i];
|
||||
}
|
||||
|
||||
|
|
@ -890,157 +887,6 @@ void Y_Ticker(void)
|
|||
}
|
||||
}
|
||||
|
||||
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.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.num[j];
|
||||
|
||||
if (i == j || ipnum == jpnum) // Same person
|
||||
continue;
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d:\n", ipnum, jpnum);
|
||||
|
||||
if (data.val[i] == data.val[j]) // Tie -- neither get any points for this match up.
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "TIE, no change.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (clientpowerlevels[jpnum][powertype] == 0) // No power level (splitscreen guests, bots)
|
||||
continue;
|
||||
|
||||
theirpower = clientpowerlevels[jpnum][powertype];
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower);
|
||||
|
||||
if ((gametyperules & GTR_CIRCUIT))
|
||||
{
|
||||
if (data.val[i] < data.val[j])
|
||||
won = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data.val[i] > data.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);
|
||||
|
||||
if (nospectategrief[jpnum] == 0) // No power level (splitscreen guests, bots)
|
||||
continue;
|
||||
|
||||
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.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.increase[i] = increment[i];
|
||||
clientpowerlevels[i][powertype] += data.increase[i];
|
||||
|
||||
if (!demo.playback && i == consoleplayer)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i);
|
||||
vspowerlevel[powertype] = clientpowerlevels[i][powertype];
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
G_SaveGameData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Y_DetermineIntermissionType
|
||||
//
|
||||
|
|
@ -1121,7 +967,7 @@ void Y_StartIntermission(void)
|
|||
//if (dedicated) return;
|
||||
|
||||
// This should always exist, but just in case...
|
||||
if(!mapheaderinfo[prevmap])
|
||||
if (!mapheaderinfo[prevmap])
|
||||
P_AllocMapHeader(prevmap);
|
||||
|
||||
switch (intertype)
|
||||
|
|
@ -1157,7 +1003,18 @@ void Y_StartIntermission(void)
|
|||
|
||||
if (powertype != PWRLV_DISABLED)
|
||||
{
|
||||
K_UpdatePowerLevels();
|
||||
for (i = 0; i < nump; i++)
|
||||
{
|
||||
// Kind of a hack to do this here,
|
||||
// but couldn't think of a better way.
|
||||
data.increase[i] = K_FinalPowerIncrement(
|
||||
&players[data.num[i]],
|
||||
clientpowerlevels[data.num[i]][powertype],
|
||||
clientPowerAdd[data.num[i]]
|
||||
);
|
||||
}
|
||||
|
||||
K_CashInPowerLevels();
|
||||
}
|
||||
|
||||
//if (intertype == int_race || intertype == int_battle)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue