mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-03-01 00:41:16 +00:00
Merge branch 'master' of git@git.magicalgirl.moe:KartKrew/Kart.git into waypoints
# Conflicts: # src/Makefile # src/k_kart.c # src/p_map.c # src/p_setup.c # src/p_spec.c
This commit is contained in:
commit
c268313f0a
72 changed files with 4745 additions and 2636 deletions
|
|
@ -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!"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -489,6 +494,7 @@ OBJS:=$(i_main_o) \
|
|||
$(OBJDIR)/y_inter.o \
|
||||
$(OBJDIR)/st_stuff.o \
|
||||
$(OBJDIR)/k_kart.o \
|
||||
$(OBJDIR)/k_pwrlv.o \
|
||||
$(OBJDIR)/k_waypoint.o\
|
||||
$(OBJDIR)/k_pathfind.o\
|
||||
$(OBJDIR)/k_bheap.o \
|
||||
|
|
|
|||
|
|
@ -68,10 +68,14 @@ 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[] = {
|
||||
{0, "Easy"}, {1, "Normal"}, {2, "Hard"},
|
||||
{0, NULL}};
|
||||
{KARTSPEED_AUTO, "Auto"},
|
||||
{KARTSPEED_EASY, "Easy"},
|
||||
{KARTSPEED_NORMAL, "Normal"},
|
||||
{KARTSPEED_HARD, "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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
145
src/d_clisrv.c
145
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
|
||||
|
|
@ -96,6 +97,8 @@ 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)
|
||||
SINT8 nodetoplayer3[MAXNETNODES]; // say the numplayer for this node if any (splitscreen == 2)
|
||||
|
|
@ -1240,6 +1243,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;
|
||||
|
|
@ -1350,7 +1354,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)
|
||||
);
|
||||
|
|
@ -1420,6 +1424,11 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
|
||||
p = PutFileNeeded(0);
|
||||
|
||||
if (cv_kartusepwrlv.value)
|
||||
netbuffer->u.serverinfo.avgpwrlv = K_CalculatePowerLevelAvg();
|
||||
else
|
||||
netbuffer->u.serverinfo.avgpwrlv = -1;
|
||||
|
||||
HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u));
|
||||
}
|
||||
|
||||
|
|
@ -1494,7 +1503,7 @@ static void SV_SendPlayerInfo(INT32 node)
|
|||
*/
|
||||
static boolean SV_SendServerConfig(INT32 node)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 i, j;
|
||||
UINT8 *p, *op;
|
||||
boolean waspacketsent;
|
||||
|
||||
|
|
@ -1517,10 +1526,13 @@ 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));
|
||||
memset(netbuffer->u.servercfg.powerlevels, 0, sizeof(netbuffer->u.servercfg.powerlevels));
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i];
|
||||
for (j = 0; j < PWRLV_NUMTYPES; j++)
|
||||
netbuffer->u.servercfg.powerlevels[i][j] = clientpowerlevels[i][j];
|
||||
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
|
@ -2306,6 +2318,7 @@ static void CL_ConnectToServer(boolean viams)
|
|||
wipegamestate = GS_WAITINGPLAYERS;
|
||||
|
||||
ClearAdminPlayers();
|
||||
K_ClearClientPowerLevels();
|
||||
pnumnodes = 1;
|
||||
oldtic = I_GetTime() - 1;
|
||||
#ifndef NONET
|
||||
|
|
@ -3156,6 +3169,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
|
||||
|
|
@ -3324,6 +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.
|
||||
K_ClearClientPowerLevels();
|
||||
}
|
||||
|
||||
mynode = 0;
|
||||
|
|
@ -3399,6 +3428,7 @@ void D_QuitNetGame(void)
|
|||
|
||||
D_CloseConnection();
|
||||
ClearAdminPlayers();
|
||||
K_ClearClientPowerLevels();
|
||||
|
||||
DEBFILE("===========================================================================\n"
|
||||
" Log finish\n"
|
||||
|
|
@ -3445,11 +3475,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_Debug(DBG_NETPLAY, "addplayer: %d %d %d\n", node, newplayernum, splitscreenplayer);
|
||||
|
||||
// Clear player before joining, lest some things get set incorrectly
|
||||
CL_ClearPlayer(newplayernum);
|
||||
|
||||
|
|
@ -3466,7 +3497,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
if (splitscreenplayer)
|
||||
{
|
||||
displayplayers[splitscreenplayer] = newplayernum;
|
||||
DEBFILE(va("spawning one of my sister number %d\n", splitscreenplayer));
|
||||
DEBFILE(va("spawning sister # %d\n", splitscreenplayer));
|
||||
if (splitscreenplayer == 1 && botingame)
|
||||
players[newplayernum].bot = 1;
|
||||
}
|
||||
|
|
@ -3477,6 +3508,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
displayplayers[i] = newplayernum;
|
||||
DEBFILE("spawning me\n");
|
||||
}
|
||||
|
||||
D_SendPlayerConfig();
|
||||
addedtogame = true;
|
||||
}
|
||||
|
|
@ -3532,7 +3564,6 @@ 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;
|
||||
|
||||
// What is the reason for this? Why can't newplayernum always be 0?
|
||||
|
|
@ -3545,6 +3576,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
|
||||
|
|
@ -3552,8 +3586,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;
|
||||
|
|
@ -3565,28 +3601,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)
|
||||
|
|
@ -3623,6 +3654,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 false;
|
||||
#else
|
||||
if (demo.playback)
|
||||
G_StopDemo(); // reset engine parameter
|
||||
if (metalplayback)
|
||||
|
|
@ -3649,6 +3685,7 @@ boolean SV_SpawnServer(void)
|
|||
}
|
||||
|
||||
return SV_AddWaitingPlayers();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SV_StopServer(void)
|
||||
|
|
@ -4075,7 +4112,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)
|
||||
|
|
@ -4098,7 +4135,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 < PWRLV_NUMTYPES; k++)
|
||||
clientpowerlevels[j][k] = netbuffer->u.servercfg.powerlevels[j][k];
|
||||
}
|
||||
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
||||
}
|
||||
|
||||
|
|
@ -4921,6 +4962,9 @@ static void CL_SendClientCmd(void)
|
|||
size_t packetsize = 0;
|
||||
boolean mis = false;
|
||||
|
||||
if (lowest_lag && ( gametic % lowest_lag ))
|
||||
return;
|
||||
|
||||
netbuffer->packettype = PT_CLIENTCMD;
|
||||
|
||||
if (cl_packetmissed)
|
||||
|
|
@ -5389,16 +5433,65 @@ static tic_t gametime = 0;
|
|||
|
||||
static void UpdatePingTable(void)
|
||||
{
|
||||
tic_t 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "d_netcmd.h"
|
||||
#include "tables.h"
|
||||
#include "d_player.h"
|
||||
#include "k_pwrlv.h" // PWRLV_NUMTYPES
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
|
|
@ -325,6 +326,7 @@ typedef struct
|
|||
UINT8 gametype;
|
||||
UINT8 modifiedgame;
|
||||
SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed
|
||||
UINT16 powerlevels[MAXPLAYERS][PWRLV_NUMTYPES]; // SRB2kart: player power levels
|
||||
|
||||
char server_context[8]; // Unique context id, generated at server startup.
|
||||
|
||||
|
|
@ -387,6 +389,10 @@ 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;
|
||||
|
||||
typedef struct
|
||||
|
|
@ -537,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,
|
||||
|
|
|
|||
41
src/d_main.c
41
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)
|
||||
{
|
||||
|
|
@ -325,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);
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK, "FADEMAP0", false, false);
|
||||
}
|
||||
|
||||
if (gamestate != GS_LEVEL && rendermode != render_none)
|
||||
|
|
@ -447,7 +440,7 @@ static void D_Display(void)
|
|||
{
|
||||
if (i > 0) // Splitscreen-specific
|
||||
{
|
||||
switch (i)
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
if (splitscreen > 1)
|
||||
|
|
@ -556,7 +549,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, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -896,11 +889,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 +915,7 @@ static void IdentifyVersion(void)
|
|||
MUSICTEST("music.wad")
|
||||
#undef MUSICTEST
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
|
|
@ -1182,12 +1183,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);
|
||||
|
||||
|
|
@ -1200,7 +1201,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 +1209,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
|
||||
|
|
@ -1241,8 +1242,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);
|
||||
|
||||
//
|
||||
|
|
@ -1534,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;
|
||||
}
|
||||
|
||||
|
|
@ -1557,7 +1560,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"))
|
||||
|
|
|
|||
106
src/d_netcmd.c
106
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
|
||||
|
|
@ -61,6 +62,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);
|
||||
|
|
@ -91,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);
|
||||
|
|
@ -358,12 +362,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}};
|
||||
|
|
@ -373,6 +378,8 @@ 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};
|
||||
|
||||
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};
|
||||
static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
|
||||
|
|
@ -411,7 +418,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};
|
||||
|
||||
|
|
@ -420,13 +428,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};
|
||||
|
|
@ -443,6 +451,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_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};
|
||||
|
||||
|
|
@ -501,6 +511,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
|||
"MODIFYVOTE",
|
||||
"PICKVOTE",
|
||||
"REMOVEPLAYER",
|
||||
"POWERLEVEL",
|
||||
#ifdef HAVE_BLUA
|
||||
"LUACMD",
|
||||
"LUAVAR"
|
||||
|
|
@ -538,6 +549,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);
|
||||
|
|
@ -705,6 +717,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);
|
||||
|
||||
|
|
@ -1925,6 +1938,17 @@ 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][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);
|
||||
}
|
||||
|
||||
void D_SendPlayerConfig(void)
|
||||
{
|
||||
SendNameAndColor();
|
||||
|
|
@ -1941,6 +1965,31 @@ void D_SendPlayerConfig(void)
|
|||
SendWeaponPref3();
|
||||
if (splitscreen > 2)
|
||||
SendWeaponPref4();
|
||||
|
||||
{
|
||||
UINT8 buf[4];
|
||||
UINT8 *buf_p = buf;
|
||||
|
||||
WRITEUINT16(buf_p, vspowerlevel[PWRLV_RACE]);
|
||||
WRITEUINT16(buf_p, vspowerlevel[PWRLV_BATTLE]);
|
||||
|
||||
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!
|
||||
|
|
@ -2353,7 +2402,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);
|
||||
|
|
@ -2524,7 +2573,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"))
|
||||
{
|
||||
|
|
@ -3651,6 +3700,9 @@ 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;
|
||||
|
|
@ -4724,6 +4776,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.
|
||||
|
|
@ -4745,8 +4805,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())
|
||||
|
|
@ -4796,9 +4856,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
|
||||
CV_SetValue(&cv_pointlimit, 0);
|
||||
CV_SetValue(&cv_timelimit, 0);
|
||||
// default settings for match: 2 mins, no pointlimit
|
||||
CV_SetValue(&cv_pointlimit, 0);
|
||||
CV_SetValue(&cv_timelimit, 120);
|
||||
}
|
||||
if (!cv_itemrespawntime.changed)
|
||||
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
|
||||
|
|
@ -5104,7 +5164,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)
|
||||
|
|
@ -5734,22 +5794,24 @@ 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_StealthSetValue(&cv_kartspeed, 1);
|
||||
CV_StealthSet(&cv_kartspeed, cv_kartspeed.defaultvalue);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5757,10 +5819,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
@ -145,6 +145,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;
|
||||
|
||||
|
|
@ -179,9 +180,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;
|
||||
|
|
|
|||
|
|
@ -326,6 +326,10 @@ 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
|
||||
k_springstars, // Spawn stars around a player when they hit a spring
|
||||
k_springcolor, // Color of spring stars
|
||||
k_killfield, // How long have you been in the kill field, stay in too long and lose a bumper
|
||||
|
||||
NUMKARTSTUFF
|
||||
} kartstufftype_t;
|
||||
|
|
|
|||
218
src/dehacked.c
218
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"))
|
||||
|
|
@ -1773,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"},
|
||||
|
|
@ -2552,6 +2552,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 >= PWRLV_NUMTYPES)
|
||||
{
|
||||
deh_warning("Power level type %d out of range (0 - %d)", x1, PWRLV_NUMTYPES-1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ((offset=0) || fastcmp(params[0], "GAMECLEAR")
|
||||
|| (++offset && fastcmp(params[0], "ALLEMERALDS")))
|
||||
//|| (++offset && fastcmp(params[0], "ULTIMATECLEAR")))
|
||||
|
|
@ -2604,7 +2617,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -3256,29 +3269,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 +3327,13 @@ 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;
|
||||
else if (fastcmp(pword, "TOWHITE"))
|
||||
wipeoffset = wipe_encore_towhite;
|
||||
}
|
||||
|
||||
if (wipeoffset < 0)
|
||||
|
|
@ -3344,10 +3343,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;
|
||||
}
|
||||
|
|
@ -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",
|
||||
|
|
@ -5609,44 +5591,77 @@ 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",
|
||||
|
||||
// Grey Spring
|
||||
"S_GREYSPRING1",
|
||||
"S_GREYSPRING2",
|
||||
"S_GREYSPRING3",
|
||||
"S_GREYSPRING4",
|
||||
|
||||
// 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",
|
||||
|
||||
// Grey Diagonal Spring
|
||||
"S_GDIAG1",
|
||||
"S_GDIAG2",
|
||||
"S_GDIAG3",
|
||||
"S_GDIAG4",
|
||||
|
||||
// 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",
|
||||
|
||||
// Grey Horizontal Spring
|
||||
"S_GHORIZ1",
|
||||
"S_GHORIZ2",
|
||||
"S_GHORIZ3",
|
||||
"S_GHORIZ4",
|
||||
|
||||
// Rain
|
||||
"S_RAIN1",
|
||||
|
|
@ -5657,6 +5672,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",
|
||||
|
|
@ -6271,26 +6291,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",
|
||||
|
||||
// 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",
|
||||
|
|
@ -6766,9 +6766,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",
|
||||
|
|
@ -7199,6 +7196,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_DRAFTDUST4",
|
||||
"S_DRAFTDUST5",
|
||||
|
||||
"S_TIREGREASE",
|
||||
|
||||
"S_OVERTIMEFOG",
|
||||
"S_OVERTIMEORB",
|
||||
"S_OVERTIMEBEAM",
|
||||
|
||||
#ifdef SEENAMES
|
||||
"S_NAMECHECK",
|
||||
#endif
|
||||
|
|
@ -7328,15 +7331,23 @@ 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_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
|
||||
"MT_SIGN", // Level end sign
|
||||
"MT_SIGN_PIECE",
|
||||
"MT_SPIKEBALL", // Spike Ball
|
||||
"MT_SPECIALSPIKEBALL",
|
||||
"MT_SPINFIRE",
|
||||
|
|
@ -7563,6 +7574,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
|
||||
|
|
@ -7714,9 +7726,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_SRB1_GENREX",
|
||||
|
||||
// SRB2kart
|
||||
"MT_GRAYSPRING",
|
||||
"MT_INVISSPRING",
|
||||
"MT_BLUEDIAG",
|
||||
"MT_RANDOMITEM",
|
||||
"MT_RANDOMITEMPOP",
|
||||
"MT_FLOATINGITEM",
|
||||
|
|
@ -7826,8 +7835,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_LAMPPOST",
|
||||
"MT_MOSSYTREE",
|
||||
|
||||
"MT_SHADOW",
|
||||
|
||||
"MT_BUMP",
|
||||
|
||||
"MT_FLINGENERGY",
|
||||
|
|
@ -7987,6 +7994,11 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_KARMAFIREWORK",
|
||||
"MT_RINGSPARKS",
|
||||
"MT_DRAFTDUST",
|
||||
"MT_TIREGREASE",
|
||||
|
||||
"MT_OVERTIMEFOG",
|
||||
"MT_OVERTIMEORB",
|
||||
"MT_OVERTIMEBEAM",
|
||||
|
||||
#ifdef SEENAMES
|
||||
"MT_NAMECHECK",
|
||||
|
|
@ -8469,7 +8481,11 @@ static const char *const KARTSTUFF_LIST[] = {
|
|||
"GETSPARKS",
|
||||
"JAWZTARGETDELAY",
|
||||
"SPECTATEWAIT",
|
||||
"GROWCANCEL"
|
||||
"GROWCANCEL",
|
||||
"TIREGREASE",
|
||||
"SPRINGSTARS",
|
||||
"SPRINGCOLOR",
|
||||
"KILLFIELD"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -8664,10 +8680,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},
|
||||
|
||||
|
|
@ -9899,11 +9915,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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -41,18 +41,36 @@ 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;
|
||||
} precipprops_t;
|
||||
|
||||
extern precipprops_t precipprops[MAXPRECIP];
|
||||
|
||||
// Set if homebrew PWAD stuff has been added.
|
||||
extern boolean modifiedgame;
|
||||
|
|
@ -227,7 +245,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.
|
||||
|
|
@ -435,6 +453,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;
|
||||
|
|
@ -474,7 +493,6 @@ extern tic_t wantedcalcdelay;
|
|||
extern tic_t indirectitemcooldown;
|
||||
extern tic_t hyubgone;
|
||||
extern tic_t mapreset;
|
||||
extern UINT8 nospectategrief;
|
||||
extern boolean thwompsactive;
|
||||
extern SINT8 spbplace;
|
||||
|
||||
|
|
@ -486,6 +504,15 @@ extern INT16 votelevels[5][2];
|
|||
extern SINT8 votes[MAXPLAYERS];
|
||||
extern SINT8 pickedvote;
|
||||
|
||||
/** Battle overtime information
|
||||
*/
|
||||
extern struct battleovertime
|
||||
{
|
||||
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;
|
||||
|
||||
extern tic_t hidetime;
|
||||
|
||||
extern UINT32 timesBeaten; // # of times the game has been beaten.
|
||||
|
|
|
|||
|
|
@ -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_intro_toblack], 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);
|
||||
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);
|
||||
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);
|
||||
F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeoutid, true, NULL, false, false);
|
||||
}
|
||||
|
||||
V_DrawString(textxpos, textypos, 0, cutscene_disptext);
|
||||
|
|
|
|||
|
|
@ -74,12 +74,13 @@ 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, boolean encorewiggle);
|
||||
|
||||
enum
|
||||
{
|
||||
wipe_credits_intermediate, // makes a good 0 I guess.
|
||||
|
||||
// Gamestate wipes
|
||||
wipe_level_toblack,
|
||||
wipe_intermission_toblack,
|
||||
wipe_voting_toblack,
|
||||
|
|
@ -92,11 +93,11 @@ enum
|
|||
wipe_intro_toblack,
|
||||
wipe_cutscene_toblack,
|
||||
|
||||
// custom intermissions
|
||||
wipe_specinter_toblack,
|
||||
wipe_multinter_toblack,
|
||||
wipe_speclevel_towhite,
|
||||
// Specialized wipes
|
||||
wipe_encore_toinvert,
|
||||
wipe_encore_towhite,
|
||||
|
||||
// "From black" wipes
|
||||
wipe_level_final,
|
||||
wipe_intermission_final,
|
||||
wipe_voting_final,
|
||||
|
|
@ -109,10 +110,6 @@ enum
|
|||
wipe_intro_final,
|
||||
wipe_cutscene_final,
|
||||
|
||||
// custom intermissions
|
||||
wipe_specinter_final,
|
||||
wipe_multinter_final,
|
||||
|
||||
NUMWIPEDEFS,
|
||||
WIPEFINALSHIFT = wipe_level_final - wipe_level_toblack
|
||||
};
|
||||
|
|
|
|||
149
src/f_wipe.c
149
src/f_wipe.c
|
|
@ -16,8 +16,10 @@
|
|||
#include "i_video.h"
|
||||
#include "v_video.h"
|
||||
|
||||
#include "r_data.h" // NearestColor
|
||||
#include "r_draw.h" // transtable
|
||||
#include "p_pspr.h" // tr_transxxx
|
||||
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
|
|
@ -47,35 +49,31 @@ 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
|
||||
72, // wipe_encore_toinvert
|
||||
99, // wipe_encore_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
|
||||
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)
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
@ -86,9 +84,13 @@ 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)
|
||||
static UINT8 pallen;
|
||||
static fixed_t paldiv;
|
||||
|
||||
/** Create fademask_t from lump
|
||||
|
|
@ -181,7 +183,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
|
||||
|
|
@ -199,6 +201,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;
|
||||
|
|
@ -242,6 +248,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];
|
||||
|
|
@ -250,28 +258,31 @@ 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 == 10)
|
||||
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
|
||||
{
|
||||
// pointer to transtable that this mask would use
|
||||
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
|
||||
transtbl = transtables + ((9 - m)<<FF_TRANSSHIFT);
|
||||
|
||||
// DRAWING LOOP
|
||||
while (draw_linestogo--)
|
||||
|
|
@ -282,7 +293,17 @@ static void F_DoWipe(fademask_t *fademask)
|
|||
draw_rowstogo = draw_rowend - draw_rowstart;
|
||||
|
||||
while (draw_rowstogo--)
|
||||
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
|
||||
{
|
||||
if (fadecolormap != NULL)
|
||||
{
|
||||
if (reverse)
|
||||
*w++ = fadecolormap[ ( m << 8 ) + *e++ ];
|
||||
else
|
||||
*w++ = fadecolormap[ ( m << 8 ) + *s++ ];
|
||||
}
|
||||
else
|
||||
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
|
||||
}
|
||||
|
||||
relativepos += vid.width;
|
||||
}
|
||||
|
|
@ -334,20 +355,86 @@ 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)
|
||||
void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean reverse, boolean encorewiggle)
|
||||
{
|
||||
#ifdef NOWIPE
|
||||
(void)wipetype;
|
||||
(void)drawMenu;
|
||||
(void)colormap;
|
||||
(void)reverse;
|
||||
(void)encorewiggle;
|
||||
#else
|
||||
tic_t nowtime;
|
||||
UINT8 wipeframe = 0;
|
||||
fademask_t *fmask;
|
||||
|
||||
paldiv = FixedDiv(257<<FRACBITS, 11<<FRACBITS);
|
||||
lumpnum_t clump = LUMPERROR;
|
||||
lighttable_t *fcolor = NULL;
|
||||
|
||||
if (colormap != NULL)
|
||||
clump = W_GetNumForName(colormap);
|
||||
|
||||
if (clump != LUMPERROR && wipetype != UINT8_MAX)
|
||||
{
|
||||
pallen = 32;
|
||||
fcolor = Z_MallocAlign((256 * pallen), PU_STATIC, NULL, 8);
|
||||
W_ReadLump(clump, fcolor);
|
||||
}
|
||||
else
|
||||
{
|
||||
pallen = 11;
|
||||
reverse = false;
|
||||
}
|
||||
|
||||
paldiv = FixedDiv(257<<FRACBITS, pallen<<FRACBITS);
|
||||
|
||||
// Init the wipe
|
||||
WipeInAction = true;
|
||||
|
|
@ -372,7 +459,16 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
HWR_DoWipe(wipetype, wipeframe-1); // send in the wipe type and wipeframe because we need to cache the graphic
|
||||
else
|
||||
#endif
|
||||
F_DoWipe(fmask);
|
||||
F_DoWipe(fmask, fcolor, reverse);
|
||||
|
||||
if (encorewiggle)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_opengl)
|
||||
#endif
|
||||
F_DoEncoreWiggle(wipeframe);
|
||||
}
|
||||
|
||||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
|
||||
|
|
@ -386,6 +482,13 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
|
||||
NetKeepAlive(); // Update the network so we don't cause timeouts
|
||||
}
|
||||
|
||||
WipeInAction = false;
|
||||
|
||||
if (fcolor)
|
||||
{
|
||||
Z_Free(fcolor);
|
||||
fcolor = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
494
src/g_game.c
494
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;
|
||||
|
|
@ -82,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}, // 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
|
||||
INT16 lastmapsaved = 0; // Last map we auto-saved at
|
||||
boolean gamecomplete = false;
|
||||
|
|
@ -216,6 +230,7 @@ INT32 sneakertime = TICRATE + (TICRATE/3);
|
|||
INT32 itemtime = 8*TICRATE;
|
||||
INT32 comebacktime = 10*TICRATE;
|
||||
INT32 bumptime = 6;
|
||||
INT32 greasetics = 3*TICRATE;
|
||||
INT32 wipeoutslowtime = 20;
|
||||
INT32 wantedreduce = 5*TICRATE;
|
||||
INT32 wantedfrequency = 10*TICRATE;
|
||||
|
|
@ -260,13 +275,15 @@ 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
|
||||
struct battleovertime battleovertime;
|
||||
|
||||
// Server-sided, synched variables
|
||||
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 hyubgone; // Cooldown before hyudoro is allowed to be rerolled
|
||||
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
|
||||
boolean thwompsactive; // Thwomps activate on lap 2
|
||||
SINT8 spbplace; // SPB exists, give the person behind better items
|
||||
|
||||
|
|
@ -1777,6 +1794,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;
|
||||
|
|
@ -2336,7 +2355,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++)
|
||||
|
|
@ -2368,21 +2387,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
|
||||
}
|
||||
|
|
@ -3041,8 +3046,17 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
|
|||
continue;
|
||||
if (j == i)
|
||||
continue;
|
||||
if (players[j].score == players[i].score)
|
||||
num++;
|
||||
|
||||
if (netgame && cv_kartusepwrlv.value)
|
||||
{
|
||||
if (clientpowerlevels[j][PWRLV_RACE] == clientpowerlevels[i][PWRLV_RACE])
|
||||
num++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[j].score == players[i].score)
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
if (num > 1) // found dupes
|
||||
|
|
@ -3050,8 +3064,21 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (players[i].score > players[playernum].score || i < playernum)
|
||||
if (i < playernum)
|
||||
pos++;
|
||||
else
|
||||
{
|
||||
if (netgame && cv_kartusepwrlv.value)
|
||||
{
|
||||
if (clientpowerlevels[i][PWRLV_RACE] > clientpowerlevels[playernum][PWRLV_RACE])
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[i].score > players[playernum].score)
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3381,9 +3408,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))
|
||||
|
|
@ -3391,25 +3419,33 @@ INT16 G_SometimesGetDifferentGametype(void)
|
|||
randmapbuffer[NUMMAPS]--;
|
||||
if (encorepossible)
|
||||
{
|
||||
switch (cv_kartvoterulechanges.value)
|
||||
if (encorescramble != -1)
|
||||
encorepossible = (boolean)encorescramble; // FORCE to what was scrambled on intermission
|
||||
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)
|
||||
if (encorepossible != (cv_kartencore.value == 1))
|
||||
return (gametype|0x80);
|
||||
}
|
||||
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
|
||||
|
|
@ -3638,7 +3674,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--)
|
||||
|
|
@ -3662,6 +3698,7 @@ static void G_DoCompleted(void)
|
|||
{
|
||||
INT32 i, j = 0;
|
||||
boolean gottoken = false;
|
||||
SINT8 powertype = PWRLV_DISABLED;
|
||||
|
||||
tokenlist = 0; // Reset the list
|
||||
|
||||
|
|
@ -3800,13 +3837,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
|
||||
|
|
@ -3878,7 +3925,7 @@ void G_NextLevel(void)
|
|||
}
|
||||
|
||||
forceresetplayers = false;
|
||||
deferencoremode = (boolean)cv_kartencore.value;
|
||||
deferencoremode = (cv_kartencore.value == 1);
|
||||
}
|
||||
|
||||
gameaction = ga_worlddone;
|
||||
|
|
@ -4041,15 +4088,24 @@ 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 < PWRLV_NUMTYPES; i++) // SRB2Kart: online rank system
|
||||
vspowerlevel[i] = PWRLVRECORD_START;
|
||||
|
||||
if (M_CheckParm("-nodata"))
|
||||
return; // Don't load.
|
||||
|
||||
// Allow saving of gamedata beyond this point
|
||||
gamedataloaded = true;
|
||||
|
||||
if (M_CheckParm("-gamedata") && M_IsNextParm())
|
||||
{
|
||||
strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename);
|
||||
}
|
||||
|
||||
if (M_CheckParm("-resetdata"))
|
||||
return; // Don't load (essentially, reset).
|
||||
|
||||
|
|
@ -4074,6 +4130,13 @@ void G_LoadGameData(void)
|
|||
totalplaytime = READUINT32(save_p);
|
||||
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);
|
||||
|
||||
// Aha! Someone's been screwing with the save file!
|
||||
|
|
@ -4219,6 +4282,9 @@ void G_SaveGameData(boolean force)
|
|||
WRITEUINT32(save_p, totalplaytime);
|
||||
WRITEUINT32(save_p, matchesplayed);
|
||||
|
||||
for (i = 0; i < PWRLV_NUMTYPES; i++)
|
||||
WRITEUINT16(save_p, vspowerlevel[i]);
|
||||
|
||||
btemp = (UINT8)(savemoddata); // what used to be here was profoundly dunderheaded
|
||||
WRITEUINT8(save_p, btemp);
|
||||
|
||||
|
|
@ -4731,7 +4797,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!
|
||||
|
|
@ -4742,12 +4808,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
|
||||
|
|
@ -4889,7 +4949,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);
|
||||
|
||||
|
|
@ -5607,16 +5666,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"));
|
||||
|
|
@ -5644,10 +5696,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
|
||||
|
|
@ -5671,9 +5719,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++;
|
||||
|
|
@ -5693,18 +5738,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);
|
||||
|
|
@ -5845,15 +5884,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)
|
||||
|
|
@ -6363,20 +6395,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());
|
||||
|
|
@ -6416,6 +6443,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() ? PWRLV_BATTLE : PWRLV_RACE]);
|
||||
|
||||
// Kart speed and weight
|
||||
WRITEUINT8(demo_p, skins[player->skin].kartspeed);
|
||||
WRITEUINT8(demo_p, skins[player->skin].kartweight);
|
||||
|
|
@ -6514,18 +6544,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)
|
||||
|
|
@ -6768,13 +6793,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);
|
||||
|
|
@ -6866,12 +6884,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);
|
||||
|
|
@ -6906,16 +6918,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);
|
||||
|
||||
|
|
@ -6925,7 +6927,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--)
|
||||
{
|
||||
|
|
@ -7116,10 +7118,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);
|
||||
|
|
@ -7148,24 +7146,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.
|
||||
|
|
@ -7223,9 +7203,6 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#ifdef DEMO_COMPAT_100
|
||||
}
|
||||
#endif
|
||||
|
||||
modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT;
|
||||
multiplayer = !!(demoflags & DF_MULTIPLAYER);
|
||||
|
|
@ -7253,109 +7230,20 @@ 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)
|
||||
// ...*map* not loaded?
|
||||
if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK))
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
Z_Free(demobuffer);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// net var data
|
||||
CV_LoadNetVars(&demo_p);
|
||||
|
|
@ -7470,6 +7358,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() ? PWRLV_BATTLE : PWRLV_RACE] = READUINT16(demo_p);
|
||||
|
||||
// Kart stats, temporarily
|
||||
kartspeed[p] = READUINT8(demo_p);
|
||||
kartweight[p] = READUINT8(demo_p);
|
||||
|
|
@ -7494,10 +7385,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.
|
||||
|
||||
|
|
@ -7588,10 +7475,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);
|
||||
|
|
@ -7632,15 +7515,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
|
||||
|
|
@ -7656,41 +7533,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
|
||||
|
|
@ -7710,10 +7552,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);
|
||||
|
|
@ -7735,6 +7573,7 @@ void G_AddGhost(char *defdemoname)
|
|||
p += 16;
|
||||
|
||||
p += 4; // score
|
||||
p += 2; // powerlevel
|
||||
|
||||
kartspeed = READUINT8(p);
|
||||
kartweight = READUINT8(p);
|
||||
|
|
@ -7746,9 +7585,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))
|
||||
|
|
@ -7848,18 +7684,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
|
||||
|
|
@ -7879,43 +7710,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
|
||||
|
|
@ -8000,10 +7810,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"));
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -3563,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! :)
|
||||
|
|
@ -4058,37 +4062,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 +4102,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 +4288,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 +4690,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 +5302,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 +5323,7 @@ static void HWR_DrawSprites(void)
|
|||
else
|
||||
HWR_DrawMD2(spr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5882,10 +5761,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;
|
||||
}
|
||||
|
||||
|
|
@ -5922,13 +5798,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 +5830,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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,188 @@ 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)>>FRACBITS);
|
||||
blendcolor.s.green = (UINT8)(FixedSqrt((g/div)<<FRACBITS)>>FRACBITS);
|
||||
blendcolor.s.blue = (UINT8)(FixedSqrt((b/div)<<FRACBITS)>>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;
|
||||
SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
||||
}
|
||||
}
|
||||
|
||||
tempmult = (blendimage->s.red-127)*2;
|
||||
if (tempmult > 255)
|
||||
tempmult = 255;
|
||||
else if (tempmult < 0)
|
||||
tempmult = 0;
|
||||
// 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;
|
||||
|
||||
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;
|
||||
// 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 > 253 || brightness < 2)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
cur++; image++; blendimage++;
|
||||
blendcolor = V_GetColor(colortranslations[color][firsti]);
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
UINT32 tempcolor;
|
||||
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);
|
||||
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
|
||||
{
|
||||
// Color strength depends on image alpha
|
||||
INT32 tempcolor;
|
||||
|
||||
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) + ((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) + ((blendcolor.s.blue * blendimage->s.alpha) / 255);
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.blue = (UINT8)tempcolor;
|
||||
cur->s.alpha = image->s.alpha;
|
||||
}
|
||||
|
||||
cur++; image++; blendimage++;
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -1091,11 +1176,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));
|
||||
|
|
|
|||
|
|
@ -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[1+gamespeed].strvalue);
|
||||
}
|
||||
|
||||
// When you play, you quickly see your score because your name is displayed in white.
|
||||
|
|
|
|||
805
src/info.c
805
src/info.c
File diff suppressed because it is too large
Load diff
169
src/info.h
169
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
|
||||
|
|
@ -459,15 +458,23 @@ 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_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
|
||||
SPR_SNO1, // Snowflake
|
||||
SPR_SNO2, // Blizzard Snowball
|
||||
SPR_SPLH, // Water Splish
|
||||
SPR_SPLA, // Water Splash
|
||||
SPR_SMOK,
|
||||
|
|
@ -587,9 +594,6 @@ typedef enum sprite
|
|||
SPR_SRBO,
|
||||
|
||||
// Springs
|
||||
SPR_SPRG, // Gray Spring
|
||||
SPR_BSPR, // Blue Diagonal Spring
|
||||
|
||||
SPR_RNDM, // Random Item Box
|
||||
SPR_RPOP, // Random Item Box Pop
|
||||
SPR_SGNS, // Signpost sparkle
|
||||
|
|
@ -635,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
|
||||
|
|
@ -778,6 +781,9 @@ typedef enum sprite
|
|||
SPR_MXCL,
|
||||
SPR_RGSP,
|
||||
SPR_DRAF,
|
||||
SPR_GRES,
|
||||
|
||||
SPR_OTFG,
|
||||
|
||||
// Xmas-specific sprites that don't fit aboxe
|
||||
SPR_XMS4,
|
||||
|
|
@ -1769,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,
|
||||
|
|
@ -2491,44 +2480,77 @@ 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,
|
||||
|
||||
// Grey Spring
|
||||
S_GREYSPRING1,
|
||||
S_GREYSPRING2,
|
||||
S_GREYSPRING3,
|
||||
S_GREYSPRING4,
|
||||
|
||||
// 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,
|
||||
|
||||
// Grey Diagonal Spring
|
||||
S_GDIAG1,
|
||||
S_GDIAG2,
|
||||
S_GDIAG3,
|
||||
S_GDIAG4,
|
||||
|
||||
// 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,
|
||||
|
||||
// Grey Horizontal Spring
|
||||
S_GHORIZ1,
|
||||
S_GHORIZ2,
|
||||
S_GHORIZ3,
|
||||
S_GHORIZ4,
|
||||
|
||||
// Rain
|
||||
S_RAIN1,
|
||||
|
|
@ -2539,6 +2561,11 @@ typedef enum state
|
|||
S_SNOW2,
|
||||
S_SNOW3,
|
||||
|
||||
// Blizzard Snowball
|
||||
S_BLIZZARDSNOW1,
|
||||
S_BLIZZARDSNOW2,
|
||||
S_BLIZZARDSNOW3,
|
||||
|
||||
// Water Splish
|
||||
S_SPLISH1,
|
||||
S_SPLISH2,
|
||||
|
|
@ -3153,26 +3180,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,
|
||||
|
||||
// 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,
|
||||
|
|
@ -3648,9 +3655,6 @@ typedef enum state
|
|||
S_LAMPPOST,
|
||||
S_MOSSYTREE,
|
||||
|
||||
S_SHADOW,
|
||||
S_WHITESHADOW,
|
||||
|
||||
S_BUMP1,
|
||||
S_BUMP2,
|
||||
S_BUMP3,
|
||||
|
|
@ -4096,6 +4100,12 @@ typedef enum state
|
|||
S_DRAFTDUST4,
|
||||
S_DRAFTDUST5,
|
||||
|
||||
S_TIREGREASE,
|
||||
|
||||
S_OVERTIMEFOG,
|
||||
S_OVERTIMEORB,
|
||||
S_OVERTIMEBEAM,
|
||||
|
||||
#ifdef SEENAMES
|
||||
S_NAMECHECK,
|
||||
#endif
|
||||
|
|
@ -4242,15 +4252,23 @@ typedef enum mobj_type
|
|||
// Springs and others
|
||||
MT_FAN,
|
||||
MT_STEAM, // Steam riser
|
||||
MT_BLUESPRING,
|
||||
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
|
||||
MT_SIGN, // Level end sign
|
||||
MT_SIGN_PIECE,
|
||||
MT_SPIKEBALL, // Spike Ball
|
||||
MT_SPECIALSPIKEBALL,
|
||||
MT_SPINFIRE,
|
||||
|
|
@ -4477,6 +4495,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
|
||||
|
|
@ -4628,9 +4647,6 @@ typedef enum mobj_type
|
|||
MT_SRB1_GENREX,
|
||||
|
||||
// SRB2kart
|
||||
MT_GRAYSPRING,
|
||||
MT_INVISSPRING,
|
||||
MT_BLUEDIAG,
|
||||
MT_RANDOMITEM,
|
||||
MT_RANDOMITEMPOP,
|
||||
MT_FLOATINGITEM,
|
||||
|
|
@ -4740,8 +4756,6 @@ typedef enum mobj_type
|
|||
MT_LAMPPOST,
|
||||
MT_MOSSYTREE,
|
||||
|
||||
MT_SHADOW,
|
||||
|
||||
MT_BUMP,
|
||||
|
||||
MT_FLINGENERGY,
|
||||
|
|
@ -4901,6 +4915,11 @@ typedef enum mobj_type
|
|||
MT_KARMAFIREWORK,
|
||||
MT_RINGSPARKS,
|
||||
MT_DRAFTDUST,
|
||||
MT_TIREGREASE,
|
||||
|
||||
MT_OVERTIMEFOG,
|
||||
MT_OVERTIMEORB,
|
||||
MT_OVERTIMEBEAM,
|
||||
|
||||
#ifdef SEENAMES
|
||||
MT_NAMECHECK,
|
||||
|
|
|
|||
499
src/k_kart.c
499
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
|
||||
|
|
@ -33,8 +34,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
|
||||
|
||||
|
|
@ -412,7 +411,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
|
||||
|
||||
|
|
@ -582,6 +581,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);
|
||||
|
|
@ -1535,20 +1535,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, true))
|
||||
return i-1;
|
||||
}
|
||||
|
||||
|
|
@ -1563,25 +1559,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;
|
||||
|
|
@ -1625,7 +1612,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 % 11));
|
||||
P_SetScale(band, (band->destscale = (3*player->mo->scale)/2));
|
||||
band->color = colors[c];
|
||||
band->colorized = true;
|
||||
|
|
@ -2322,6 +2309,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
|
||||
|
|
@ -4344,6 +4334,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)
|
||||
{
|
||||
|
|
@ -4528,6 +4679,14 @@ 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
|
||||
if (P_IsObjectOnGround(cur))
|
||||
{
|
||||
K_CalculateBananaSlope(cur, cur->x, cur->y, cur->z,
|
||||
cur->radius, cur->height, (cur->eflags & MFE_VERTICALFLIP), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
cur = cur->hnext;
|
||||
}
|
||||
}
|
||||
|
|
@ -4617,6 +4776,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;
|
||||
}
|
||||
|
|
@ -5060,6 +5222,29 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
if (P_IsDisplayPlayer(player))
|
||||
debtflag->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
|
||||
|
|
@ -5103,6 +5288,25 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
player->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 if (player->kartstuff[k_ringboost] && (leveltime & 1)) // ring boosting
|
||||
{
|
||||
player->mo->colorized = true;
|
||||
|
|
@ -5262,6 +5466,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)
|
||||
{
|
||||
|
|
@ -5271,8 +5478,28 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
K_KartPlayerHUDUpdate(player);
|
||||
|
||||
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 >= 10*TICRATE)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
|
@ -5302,17 +5529,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;
|
||||
|
||||
|
|
@ -5446,15 +5662,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
|
||||
basedrift += (basedrift / greasetics) * player->kartstuff[k_tiregrease];
|
||||
|
||||
return basedrift + FixedMul(driftangle, countersteer);
|
||||
}
|
||||
|
||||
|
|
@ -6146,7 +6363,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;
|
||||
|
|
@ -6206,6 +6423,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;
|
||||
|
|
@ -6714,6 +6932,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])
|
||||
{
|
||||
|
|
@ -6726,9 +6950,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)
|
||||
|
|
@ -6739,23 +6974,14 @@ 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);
|
||||
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.
|
||||
|
|
@ -7229,6 +7455,10 @@ static patch_t *kp_lapanim_emblem[2];
|
|||
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)
|
||||
{
|
||||
|
|
@ -7529,6 +7759,21 @@ 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
|
||||
|
|
@ -8501,9 +8746,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
|
||||
|
|
@ -8524,15 +8771,39 @@ 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);
|
||||
|
||||
y2 = y;
|
||||
|
||||
if (tab[i].num == 0 && server_lagless)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
@ -9054,7 +9325,7 @@ static void K_drawKartPlayerCheck(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags, patch_t *AutomapPic)
|
||||
static void K_drawKartMinimapIcon(fixed_t objx, fixed_t objy, INT32 hudx, INT32 hudy, INT32 flags, patch_t *icon, UINT8 *colormap, patch_t *AutomapPic)
|
||||
{
|
||||
// amnum xpos & ypos are the icon's speed around the HUD.
|
||||
// The number being divided by is for how fast it moves.
|
||||
|
|
@ -9063,8 +9334,6 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags, pat
|
|||
// am xpos & ypos are the icon's starting position. Withouht
|
||||
// it, they wouldn't 'spawn' on the top-right side of the HUD.
|
||||
|
||||
UINT8 skin = 0;
|
||||
|
||||
fixed_t amnumxpos, amnumypos;
|
||||
INT32 amxpos, amypos;
|
||||
|
||||
|
|
@ -9075,9 +9344,6 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags, pat
|
|||
fixed_t xoffset, yoffset;
|
||||
fixed_t xscale, yscale, zoom;
|
||||
|
||||
if (mo->skin)
|
||||
skin = ((skin_t*)mo->skin)-skins;
|
||||
|
||||
maxx = maxy = INT32_MAX;
|
||||
minx = miny = INT32_MIN;
|
||||
minx = bsp->bbox[0][BOXLEFT];
|
||||
|
|
@ -9114,39 +9380,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))<<FRACBITS);
|
||||
amypos = amnumypos + ((y + AutomapPic->height/2 - (facemmapprefix[skin]->height/2))<<FRACBITS);
|
||||
amxpos = amnumxpos + ((hudx + AutomapPic->width/2 - (icon->width/2))<<FRACBITS);
|
||||
amypos = amnumypos + ((hudy + AutomapPic->height/2 - (icon->height/2))<<FRACBITS);
|
||||
|
||||
// do we want this? it feels unnecessary. easier to just modify the amnumxpos?
|
||||
/*if (encoremode)
|
||||
{
|
||||
flags |= V_FLIP;
|
||||
amxpos = -amnumxpos + ((x + AutomapPic->width/2 + (facemmapprefix[skin]->width/2))<<FRACBITS);
|
||||
amxpos = -amnumxpos + ((hudx + AutomapPic->width/2 + (icon->width/2))<<FRACBITS);
|
||||
}*/
|
||||
|
||||
if (!mo->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);
|
||||
if (mo->player
|
||||
&& ((G_RaceGametype() && mo->player->kartstuff[k_position] == spbplace)
|
||||
|| (G_BattleGametype() && K_IsPlayerWanted(mo->player))))
|
||||
{
|
||||
V_DrawFixedPatch(amxpos - (4<<FRACBITS), amypos - (4<<FRACBITS), FRACUNIT, flags, kp_wantedreticle, NULL);
|
||||
}
|
||||
}
|
||||
V_DrawFixedPatch(amxpos, amypos, FRACUNIT, flags, icon, colormap);
|
||||
}
|
||||
|
||||
static void K_drawKartMinimap(void)
|
||||
|
|
@ -9155,7 +9405,9 @@ static void K_drawKartMinimap(void)
|
|||
patch_t *AutomapPic;
|
||||
INT32 i = 0;
|
||||
INT32 x, y;
|
||||
INT32 minimaptrans, splitflags = (splitscreen == 3 ? 0 : V_SNAPTORIGHT); // flags should only be 0 when it's centered (4p split)
|
||||
INT32 minimaptrans, splitflags = (splitscreen == 3 ? 0 : V_SNAPTORIGHT); // flags should only be 0 when it's centered (4p split)
|
||||
UINT8 skin = 0;
|
||||
UINT8 *colormap = NULL;
|
||||
SINT8 localplayers[4];
|
||||
SINT8 numlocalplayers = 0;
|
||||
|
||||
|
|
@ -9164,6 +9416,8 @@ static void K_drawKartMinimap(void)
|
|||
if (gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
// Only draw for the first player
|
||||
// Maybe move this somewhere else where this won't be a concern?
|
||||
if (stplyr != &players[displayplayers[0]])
|
||||
return;
|
||||
|
||||
|
|
@ -9209,6 +9463,20 @@ static void K_drawKartMinimap(void)
|
|||
x -= SHORT(AutomapPic->leftoffset);
|
||||
y -= SHORT(AutomapPic->topoffset);
|
||||
|
||||
// Draw the super item in Battle
|
||||
if (G_BattleGametype() && battleovertime.enabled)
|
||||
{
|
||||
if (battleovertime.enabled >= 10*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_drawKartMinimapIcon(battleovertime.x, battleovertime.y, x, y, splitflags, kp_itemminimap, colormap, AutomapPic);
|
||||
splitflags = prevsplitflags;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize
|
||||
for (i = 0; i < 4; i++)
|
||||
localplayers[i] = -1;
|
||||
|
|
@ -9219,7 +9487,20 @@ static void K_drawKartMinimap(void)
|
|||
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_drawKartMinimapIcon(g->mo->x, g->mo->y, x, y, splitflags, facemmapprefix[skin], colormap, AutomapPic);
|
||||
g = g->next;
|
||||
}
|
||||
|
||||
|
|
@ -9252,7 +9533,7 @@ static void K_drawKartMinimap(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (P_IsDisplayPlayer(&players[i]))
|
||||
if (i == displayplayers[0] || i == displayplayers[1] || i == displayplayers[2] || i == displayplayers[3])
|
||||
{
|
||||
// Draw display players on top of everything else
|
||||
localplayers[numlocalplayers] = i;
|
||||
|
|
@ -9260,7 +9541,26 @@ 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_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, facemmapprefix[skin], colormap, AutomapPic);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -9272,7 +9572,28 @@ static void K_drawKartMinimap(void)
|
|||
{
|
||||
if (i == -1)
|
||||
continue; // this doesn't interest us
|
||||
K_drawKartMinimapHead(players[localplayers[i]].mo, x, y, splitflags, AutomapPic);
|
||||
|
||||
if (players[localplayers[i]].mo->skin)
|
||||
skin = ((skin_t*)players[localplayers[i]].mo->skin)-skins;
|
||||
else
|
||||
skin = 0;
|
||||
|
||||
if (players[localplayers[i]].mo->color)
|
||||
{
|
||||
if (players[localplayers[i]].mo->colorized)
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, players[localplayers[i]].mo->color, GTC_CACHE);
|
||||
else
|
||||
colormap = R_GetTranslationColormap(skin, players[localplayers[i]].mo->color, GTC_CACHE);
|
||||
}
|
||||
else
|
||||
colormap = NULL;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -9784,7 +10105,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)
|
||||
|
|
|
|||
333
src/k_pwrlv.c
Normal file
333
src/k_pwrlv.c
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
/// \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)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Not in a netgame, or not using power levels -- no average.\n");
|
||||
return 0; // No average.
|
||||
}
|
||||
|
||||
if (G_RaceGametype())
|
||||
t = PWRLV_RACE;
|
||||
else if (G_BattleGametype())
|
||||
t = PWRLV_BATTLE;
|
||||
|
||||
if (t == PWRLV_DISABLED)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Could not set a power level type -- no average.\n");
|
||||
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] << FRACBITS);
|
||||
div++;
|
||||
}
|
||||
|
||||
if (!div)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Found no players -- no average.\n");
|
||||
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_kartspeed.value == -1 || cv_kartencore.value == -1)
|
||||
{
|
||||
UINT8 speed = KARTSPEED_NORMAL;
|
||||
boolean encore = false;
|
||||
INT16 avg = 0, min = 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_Debug(DBG_GAMELOGIC, "Min: %d, Avg: %d\n", min, avg);
|
||||
|
||||
if (avg == 0 || min == 0)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "No average/minimum, no scramblin'.\n");
|
||||
speedscramble = encorescramble = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (min >= 7800)
|
||||
{
|
||||
if (avg >= 8200)
|
||||
t = 5;
|
||||
else
|
||||
t = 4;
|
||||
}
|
||||
else if (min >= 6800)
|
||||
{
|
||||
if (avg >= 7200)
|
||||
t = 4;
|
||||
else
|
||||
t = 3;
|
||||
}
|
||||
else if (min >= 5800)
|
||||
{
|
||||
if (avg >= 6200)
|
||||
t = 3;
|
||||
else
|
||||
t = 2;
|
||||
}
|
||||
else if (min >= 3800)
|
||||
{
|
||||
if (avg >= 4200)
|
||||
t = 2;
|
||||
else
|
||||
t = 1;
|
||||
}
|
||||
#if 1
|
||||
else
|
||||
t = 1;
|
||||
#else
|
||||
else if (min >= 1800)
|
||||
{
|
||||
if (avg >= 2200)
|
||||
t = 1;
|
||||
else
|
||||
t = 0;
|
||||
}
|
||||
else
|
||||
t = 0;
|
||||
#endif
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Table position: %d\n", t);
|
||||
|
||||
switch (t)
|
||||
{
|
||||
case 5:
|
||||
speed = KARTSPEED_HARD;
|
||||
encore = true;
|
||||
break;
|
||||
case 4:
|
||||
speed = P_RandomChance((7<<FRACBITS)/10) ? KARTSPEED_HARD : KARTSPEED_NORMAL;
|
||||
encore = P_RandomChance(FRACUNIT>>1);
|
||||
break;
|
||||
case 3:
|
||||
speed = P_RandomChance((3<<FRACBITS)/10) ? KARTSPEED_HARD : KARTSPEED_NORMAL;
|
||||
encore = P_RandomChance(FRACUNIT>>2);
|
||||
break;
|
||||
case 2:
|
||||
speed = 1;
|
||||
encore = P_RandomChance(FRACUNIT>>3);
|
||||
break;
|
||||
case 1: default:
|
||||
speed = KARTSPEED_NORMAL;
|
||||
encore = false;
|
||||
break;
|
||||
case 0:
|
||||
speed = P_RandomChance((3<<FRACBITS)/10) ? KARTSPEED_EASY : KARTSPEED_NORMAL;
|
||||
encore = false;
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
else
|
||||
speedscramble = -1;
|
||||
|
||||
if (cv_kartencore.value == -1)
|
||||
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
31
src/k_pwrlv.h
Normal 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 // 5000?
|
||||
#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
|
||||
|
|
@ -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
|
||||
////////////
|
||||
|
||||
|
|
@ -1313,15 +1303,16 @@ 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);
|
||||
boolean touchground = lua_optboolean(L, 4);
|
||||
//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, touchground), META_SECTOR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -1405,15 +1396,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;
|
||||
}
|
||||
|
||||
|
|
@ -2672,7 +2663,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},
|
||||
|
|
@ -2736,7 +2726,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},
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -577,14 +577,14 @@ void Command_Skynum_f(void)
|
|||
|
||||
if (COM_Argc() != 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("skynum <sky#>: change the sky\n"));
|
||||
CONS_Printf(M_GetText("Current sky is %d\n"), levelskynum);
|
||||
CONS_Printf(M_GetText("skynum <texture name>: 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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -289,6 +290,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
|
||||
|
|
|
|||
45
src/m_cond.h
45
src/m_cond.h
|
|
@ -22,28 +22,29 @@ typedef enum
|
|||
{
|
||||
UC_PLAYTIME, // PLAYTIME [tics]
|
||||
UC_MATCHESPLAYED, // SRB2Kart: MATCHESPLAYED [x played]
|
||||
UC_GAMECLEAR, // GAMECLEAR <x times>
|
||||
UC_ALLEMERALDS, // ALLEMERALDS <x times>
|
||||
//UC_ULTIMATECLEAR, // ULTIMATECLEAR <x times>
|
||||
//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] <mare, omit or "0" for overall> [score to beat]
|
||||
//UC_NIGHTSTIME, // NIGHTSTIME [map number] <mare, omit "0" overall> [time to beat, tics]
|
||||
//UC_NIGHTSGRADE, // NIGHTSGRADE [map number] <mare, omit "0" overall> [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 <x times>
|
||||
UC_ALLEMERALDS, // ALLEMERALDS <x times>
|
||||
//UC_ULTIMATECLEAR, // ULTIMATECLEAR <x times>
|
||||
//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] <mare, omit or "0" for overall> [score to beat]
|
||||
//UC_NIGHTSTIME, // NIGHTSTIME [map number] <mare, omit "0" overall> [time to beat, tics]
|
||||
//UC_NIGHTSGRADE, // NIGHTSGRADE [map number] <mare, omit "0" overall> [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
|
||||
|
|
|
|||
114
src/m_menu.c
114
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
|
||||
|
|
@ -89,6 +90,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,
|
||||
|
|
@ -241,14 +246,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);
|
||||
|
|
@ -474,9 +483,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},
|
||||
};
|
||||
|
|
@ -727,7 +741,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
|
||||
|
|
@ -961,12 +977,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
|
||||
|
|
@ -1482,8 +1502,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[] =
|
||||
|
|
@ -3029,7 +3048,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 +4115,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5381,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].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)
|
||||
|
|
@ -6210,6 +6241,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 == PWRLV_BATTLE ? "Battle" : "Race"));
|
||||
case UC_GAMECLEAR:
|
||||
if (cond.requirement > 1)
|
||||
return va("Beat game %d times", cond.requirement);
|
||||
|
|
@ -7294,7 +7327,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);
|
||||
|
|
@ -7403,9 +7436,14 @@ 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, 52, highlightflags, "Online Power Level:");
|
||||
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++)
|
||||
{
|
||||
if (!mapheaderinfo[i] || !(mapheaderinfo[i]->menuflags & LF2_RECORDATTACK))
|
||||
|
|
@ -7420,18 +7458,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);
|
||||
}
|
||||
|
|
@ -8261,6 +8299,7 @@ static void M_DrawConnectMenu(void)
|
|||
UINT16 i;
|
||||
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++)
|
||||
|
|
@ -8295,33 +8334,38 @@ 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";
|
||||
if (serverlist[slindex].info.gametype < NUMGAMETYPES)
|
||||
gt = Gametype_Names[serverlist[slindex].info.gametype];
|
||||
|
||||
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));
|
||||
spd = kartspeed_cons_t[(serverlist[slindex].info.kartvars & SV_SPEEDMASK)+1].strvalue;
|
||||
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;
|
||||
}
|
||||
|
|
@ -8600,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");
|
||||
}
|
||||
|
||||
|
|
@ -8641,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
|
||||
{
|
||||
|
|
@ -8774,6 +8818,7 @@ static void M_MapChange(INT32 choice)
|
|||
M_SetupNextMenu(&MISC_ChangeLevelDef);
|
||||
}
|
||||
|
||||
#ifndef TESTERS
|
||||
static void M_StartOfflineServerMenu(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
|
@ -8781,8 +8826,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;
|
||||
|
|
@ -8792,6 +8839,7 @@ static void M_StartServerMenu(INT32 choice)
|
|||
M_SetupNextMenu(&MP_ServerDef);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
// ==============
|
||||
// CONNECT VIA IP
|
||||
|
|
@ -8811,7 +8859,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
|
||||
|
|
@ -8819,10 +8867,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;
|
||||
|
|
@ -9583,6 +9633,8 @@ static UINT8 erasecontext = 0;
|
|||
|
||||
static void M_EraseDataResponse(INT32 ch)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
if (ch != 'y' && ch != KEY_ENTER)
|
||||
return;
|
||||
|
||||
|
|
@ -9594,6 +9646,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 < PWRLV_NUMTYPES; i++)
|
||||
vspowerlevel[i] = PWRLVRECORD_START;
|
||||
F_StartIntro();
|
||||
}
|
||||
if (erasecontext != 1)
|
||||
|
|
|
|||
149
src/p_enemy.c
149
src/p_enemy.c
|
|
@ -118,7 +118,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);
|
||||
|
|
@ -3559,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;
|
||||
|
|
@ -3604,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++;
|
||||
}
|
||||
}
|
||||
|
|
@ -3636,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 + actor->target->scale * 24 * P_MobjFlip(actor));
|
||||
|
||||
actor->angle += ANG30;
|
||||
actor->extravalue1++;
|
||||
|
|
@ -4187,38 +4180,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.
|
||||
|
|
@ -8300,7 +8261,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;
|
||||
|
||||
|
|
@ -8314,7 +8275,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);
|
||||
|
|
@ -8322,7 +8283,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;
|
||||
|
|
@ -8335,20 +8300,100 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
@ -2275,7 +2276,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)), false) == sec))
|
||||
continue;
|
||||
|
||||
if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec))
|
||||
|
|
|
|||
178
src/p_inter.c
178
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") : ""
|
||||
|
|
@ -924,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, false))
|
||||
{
|
||||
CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80);
|
||||
|
||||
|
|
@ -1763,6 +1764,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.
|
||||
|
|
@ -1773,7 +1777,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;
|
||||
|
|
@ -1807,71 +1811,76 @@ void P_CheckTimeLimit(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
else*/
|
||||
|
||||
//Optional tie-breaker for Match/CTF
|
||||
else*/ if (cv_overtime.value)
|
||||
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)
|
||||
INT32 b = 0;
|
||||
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)
|
||||
{
|
||||
playerarray[playercount] = i;
|
||||
playercount++;
|
||||
mobj_t *thismo;
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
thismo = (mobj_t *)th;
|
||||
|
||||
if (thismo->type != MT_RANDOMITEM)
|
||||
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 (playercount > MAXPLAYERS)
|
||||
playercount = MAXPLAYERS;
|
||||
|
||||
//Sort 'em.
|
||||
for (i = 1; i < playercount; i++)
|
||||
{
|
||||
for (k = i; k < playercount; k++)
|
||||
if (item == NULL) // no item found, could happen if every item is in the air or has ambush flag, or the map has none
|
||||
{
|
||||
if (players[playerarray[i-1]].marescore < players[playerarray[k]].marescore)
|
||||
{
|
||||
tempplayer = playerarray[i-1];
|
||||
playerarray[i-1] = playerarray[k];
|
||||
playerarray[k] = tempplayer;
|
||||
}
|
||||
CONS_Alert(CONS_WARNING, "No usuable items for Battle overtime!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//End the round if the top players aren't tied.
|
||||
if (players[playerarray[0]].marescore == players[playerarray[1]].marescore)
|
||||
return;
|
||||
item->threshold = 70; // Set constant respawn
|
||||
battleovertime.x = item->x;
|
||||
battleovertime.y = item->y;
|
||||
battleovertime.z = item->z;
|
||||
battleovertime.radius = 4096*mapobjectscale;
|
||||
battleovertime.minradius = (cv_overtime.value == 2 ? 40 : 512) * mapobjectscale;
|
||||
battleovertime.enabled = 1;
|
||||
S_StartSound(NULL, sfx_kc47);
|
||||
}
|
||||
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++)
|
||||
|
|
@ -1882,9 +1891,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.
|
||||
|
|
@ -2030,7 +2036,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++)
|
||||
|
|
@ -2047,57 +2054,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;
|
||||
}
|
||||
|
||||
|
|
@ -2142,6 +2145,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))
|
||||
|
|
|
|||
|
|
@ -211,12 +211,11 @@ 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);
|
||||
|
||||
mobj_t *P_SpawnShadowMobj(mobj_t * caster);
|
||||
|
||||
void P_RecalcPrecipInSector(sector_t *sector);
|
||||
void P_PrecipitationEffects(void);
|
||||
|
||||
|
|
@ -227,7 +226,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);
|
||||
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);
|
||||
|
|
|
|||
189
src/p_map.c
189
src/p_map.c
|
|
@ -129,6 +129,8 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
|||
// MOVEMENT ITERATOR FUNCTIONS
|
||||
// =========================================================================
|
||||
|
||||
//#define TELEPORTJANK
|
||||
|
||||
// For our intermediate buffer, remove any duplicate entries by adding each one to
|
||||
// a temprary buffer if it's not already in there, copy the temporary buffer back over the intermediate afterwards
|
||||
static void spechitint_removedups(void)
|
||||
|
|
@ -228,9 +230,11 @@ 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;
|
||||
UINT8 starcolor = (spring->info->painchance % MAXTRANSLATIONS);
|
||||
fixed_t savemomx = 0;
|
||||
fixed_t savemomy = 0;
|
||||
|
||||
if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
|
||||
return false;
|
||||
|
|
@ -252,29 +256,36 @@ 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;
|
||||
|
||||
// Vertical springs teleport you on TOP of them.
|
||||
if (vertispeed > 0)
|
||||
object->z = spring->z + spring->height + 1;
|
||||
else if (vertispeed < 0)
|
||||
object->z = spring->z - object->height - 1;
|
||||
else
|
||||
{
|
||||
fixed_t offx, offy;
|
||||
|
||||
// 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);
|
||||
|
||||
// Make it square by clipping
|
||||
// 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))
|
||||
|
|
@ -285,27 +296,94 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
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);
|
||||
}
|
||||
|
||||
if (vertispeed)
|
||||
object->momz = FixedMul(vertispeed,FixedSqrt(FixedMul(vscale, spring->scale)));
|
||||
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))));
|
||||
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);
|
||||
|
||||
if (!vertispeed)
|
||||
{
|
||||
fixed_t finalSpeed = FixedDiv(horizspeed, hscale);
|
||||
fixed_t pSpeed = object->player->speed;
|
||||
// Scale to gamespeed
|
||||
finalSpeed = FixedMul(finalSpeed, K_GetKartGameSpeedScalar(gamespeed));
|
||||
|
||||
if (pSpeed > finalSpeed)
|
||||
finalSpeed = pSpeed;
|
||||
// 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)
|
||||
{
|
||||
angle_t momang;
|
||||
INT32 angoffset;
|
||||
boolean subtract = false;
|
||||
|
||||
P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(finalSpeed,FixedSqrt(FixedMul(hscale, spring->scale))));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (object->player)
|
||||
{
|
||||
// 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
|
||||
finalSpeed = max(objectSpeed, finalSpeed);
|
||||
|
||||
P_InstaThrustEvenIn2D(object, finalAngle, FixedMul(finalSpeed, FixedSqrt(FixedMul(hscale, spring->scale))));
|
||||
}
|
||||
|
||||
// Re-solidify
|
||||
|
|
@ -318,46 +396,12 @@ 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//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);
|
||||
}
|
||||
*/
|
||||
object->player->kartstuff[k_springstars] = max(vertispeed, horizspeed) / FRACUNIT / 2;
|
||||
object->player->kartstuff[k_springcolor] = starcolor;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1273,6 +1317,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)
|
||||
{
|
||||
|
|
@ -2869,27 +2914,18 @@ 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 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;
|
||||
if (thing->player && thing->player->kartstuff[k_waterskip])
|
||||
maxstep += maxstepmove; // Add some extra stepmove when waterskipping
|
||||
|
||||
// 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, false))
|
||||
maxstep <<= 1;
|
||||
// If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin
|
||||
else if (P_MobjTouchingSectorSpecial(thing, 1, 12, false))
|
||||
maxstep = 0;
|
||||
|
||||
if (thing->type == MT_SKIM)
|
||||
maxstep = 0;
|
||||
|
|
@ -2912,12 +2948,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, 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.
|
||||
|
|
@ -3019,14 +3050,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
|
||||
|
|
@ -4853,7 +4894,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;
|
||||
|
|
|
|||
1192
src/p_mobj.c
1192
src/p_mobj.c
File diff suppressed because it is too large
Load diff
37
src/p_mobj.h
37
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).
|
||||
|
|
@ -370,10 +365,16 @@ 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
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -389,6 +390,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;
|
||||
|
||||
|
|
@ -456,8 +460,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);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@
|
|||
#include "p_slopes.h"
|
||||
#endif
|
||||
|
||||
// SRB2Kart
|
||||
#include "k_pwrlv.h"
|
||||
|
||||
savedata_t savedata;
|
||||
UINT8 *save_p;
|
||||
|
||||
|
|
@ -953,8 +956,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
|
||||
|
|
@ -2150,7 +2153,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);
|
||||
|
|
@ -3106,7 +3114,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);
|
||||
|
|
@ -3125,8 +3133,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");
|
||||
|
|
@ -3139,9 +3147,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);
|
||||
|
||||
|
|
@ -3297,14 +3305,28 @@ 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]);
|
||||
|
||||
// battleovertime_t
|
||||
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);
|
||||
WRITEUINT32(save_p, hyubgone);
|
||||
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);
|
||||
|
||||
|
|
@ -3406,14 +3428,28 @@ 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);
|
||||
|
||||
// battleovertime_t
|
||||
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);
|
||||
hyubgone = 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);
|
||||
|
||||
|
|
|
|||
107
src/p_setup.c
107
src/p_setup.c
|
|
@ -84,6 +84,7 @@
|
|||
|
||||
// SRB2Kart
|
||||
#include "k_kart.h"
|
||||
#include "k_pwrlv.h"
|
||||
#include "k_waypoint.h"
|
||||
|
||||
//
|
||||
|
|
@ -181,6 +182,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);
|
||||
|
|
@ -208,8 +211,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);
|
||||
|
|
@ -245,7 +249,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
|
||||
|
|
@ -2256,17 +2260,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)
|
||||
|
|
@ -2386,22 +2391,30 @@ 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
|
||||
gamespeed = (UINT8)cv_kartspeed.value;
|
||||
{
|
||||
if (cv_kartspeed.value == KARTSPEED_AUTO)
|
||||
gamespeed = ((speedscramble == -1) ? KARTSPEED_NORMAL : (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;
|
||||
|
||||
memset(&battleovertime, 0, sizeof(struct battleovertime));
|
||||
speedscramble = encorescramble = -1;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -2779,7 +2792,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;
|
||||
|
|
@ -2858,36 +2871,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);
|
||||
|
||||
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)
|
||||
#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);
|
||||
|
||||
locstarttime = nowtime = lastwipetic;
|
||||
endtime = locstarttime + (3*TICRATE)/2;
|
||||
F_RunWipe(wipedefs[wipe_encore_towhite], false, "FADEMAP1", false, true); // wiggle the screen during this!
|
||||
|
||||
// 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, false);
|
||||
|
||||
// Wait a bit longer.
|
||||
WAIT((3*TICRATE)/4);
|
||||
}
|
||||
|
||||
// Make sure all sounds are stopped before Z_FreeTags.
|
||||
|
|
@ -2898,17 +2925,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);
|
||||
|
||||
F_RunWipe(wipedefs[wipe_level_toblack], false, ((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), false, false);
|
||||
}
|
||||
|
||||
// Reset the palette now all fades have been done
|
||||
|
|
@ -2974,7 +3002,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);
|
||||
|
||||
|
|
@ -3283,7 +3311,10 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
indirectitemcooldown = 0;
|
||||
hyubgone = 0;
|
||||
mapreset = 0;
|
||||
nospectategrief = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
nospectategrief[i] = -1;
|
||||
|
||||
thwompsactive = false;
|
||||
spbplace = -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -836,6 +836,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;
|
||||
}
|
||||
|
|
@ -852,6 +855,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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -871,33 +877,31 @@ 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
|
||||
}
|
||||
|
||||
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)));
|
||||
|
||||
|
|
|
|||
439
src/p_spec.c
439
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,54 @@ 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!
|
||||
{
|
||||
UINT8 randomstates = (UINT8)mobjinfo[swap].damage;
|
||||
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 (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 / (randomstates + 1);
|
||||
UINT8 i;
|
||||
|
||||
precipmobj->precipflags &= ~PCF_INVISIBLE;
|
||||
|
||||
precipmobj->precipflags |= PCF_RAIN;
|
||||
//think->function.acp1 = (actionf_p1)P_RainThinker;
|
||||
for (i = 0; i < 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();
|
||||
}
|
||||
|
||||
// Passed over the finish line forwards
|
||||
|
|
@ -2957,7 +2846,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
|
||||
|
|
@ -3387,6 +3276,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 = 0;
|
||||
|
||||
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 = 0;
|
||||
|
||||
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 = 2;
|
||||
|
||||
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
|
||||
//
|
||||
|
|
@ -3412,13 +3371,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;
|
||||
}
|
||||
|
|
@ -3440,14 +3393,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;
|
||||
}
|
||||
|
||||
|
|
@ -3455,14 +3401,11 @@ 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);
|
||||
thing->angle = player->mo->angle;
|
||||
P_SetupSignObject(thing, player->mo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3516,7 +3459,7 @@ boolean P_IsFlagAtBase(mobjtype_t flag)
|
|||
}
|
||||
|
||||
//
|
||||
// P_PlayerTouchingSectorSpecial
|
||||
// P_MobjTouchingSectorSpecial
|
||||
//
|
||||
// Replaces the old player->specialsector.
|
||||
// This allows a player to touch more than
|
||||
|
|
@ -3526,60 +3469,86 @@ 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: 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, boolean touchground)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
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)
|
||||
{
|
||||
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 = player->mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, section) != number)
|
||||
continue;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -3587,64 +3556,86 @@ 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;
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -3792,10 +3783,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;
|
||||
|
|
@ -5723,25 +5713,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
|
||||
|
|
|
|||
|
|
@ -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, boolean touchground);
|
||||
void P_PlayerInSpecialSector(player_t *player);
|
||||
void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector);
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ void P_CrossSpecialLine(line_t *ld, INT32 side, mobj_t *thing);
|
|||
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);
|
||||
|
|
|
|||
52
src/p_tick.c
52
src/p_tick.c
|
|
@ -59,8 +59,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"
|
||||
|
|
@ -76,14 +74,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");
|
||||
|
|
@ -618,33 +608,10 @@ void P_Ticker(boolean run)
|
|||
}
|
||||
if (demo.playback)
|
||||
{
|
||||
|
||||
#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_ReadDemoExtraData();
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
G_ReadDemoTiccmd(&players[i].cmd, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
@ -665,6 +632,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++)
|
||||
|
|
@ -680,8 +649,6 @@ void P_Ticker(boolean run)
|
|||
//P_RunShields();
|
||||
P_RunOverlays();
|
||||
|
||||
P_RunShadows();
|
||||
|
||||
P_UpdateSpecials();
|
||||
P_RespawnSpecials();
|
||||
|
||||
|
|
@ -760,11 +727,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();
|
||||
}
|
||||
|
||||
|
|
@ -827,6 +789,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++)
|
||||
|
|
|
|||
45
src/p_user.c
45
src/p_user.c
|
|
@ -1645,12 +1645,16 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
ghost->frame |= tr_trans50<<FF_TRANSSHIFT;
|
||||
ghost->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;
|
||||
}
|
||||
|
|
@ -4186,27 +4190,33 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8130,8 +8140,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.
|
||||
|
|
@ -8141,7 +8149,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)
|
||||
|
|
|
|||
17
src/r_bsp.c
17
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -1177,7 +1177,6 @@ void R_ClearColormaps(void)
|
|||
//
|
||||
static double deltas[256][3], map[256][3];
|
||||
|
||||
static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||
static int RoundUp(double number);
|
||||
|
||||
#ifdef HASINVERT
|
||||
|
|
@ -1403,7 +1402,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
|
|||
|
||||
// Thanks to quake2 source!
|
||||
// utils3/qdata/images.c
|
||||
static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b)
|
||||
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b)
|
||||
{
|
||||
int dr, dg, db;
|
||||
int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i;
|
||||
|
|
@ -1631,7 +1630,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;
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap);
|
|||
void R_ClearColormaps(void);
|
||||
INT32 R_ColormapNumForName(char *name);
|
||||
INT32 R_CreateColormap(char *p1, char *p2, char *p3);
|
||||
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||
#ifdef HASINVERT
|
||||
void R_MakeInvertmap(void);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
460
src/r_things.c
460
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<<FRACBITS)/(x2-x1+1); // fuck it
|
||||
|
||||
if (shadow->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<<FF_TRANSSHIFT);
|
||||
|
||||
if (thing->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, abs(offset2));
|
||||
|
||||
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
|
||||
// sortscale = max(yscale, yscale2);
|
||||
|
|
@ -1349,9 +1679,20 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
{
|
||||
scalestep = 0;
|
||||
yscale = sortscale;
|
||||
}
|
||||
tx += offset;
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>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;
|
||||
}
|
||||
|
|
@ -1639,14 +1988,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;
|
||||
|
|
@ -1670,6 +2015,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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
10
src/screen.c
10
src/screen.c
|
|
@ -427,13 +427,13 @@ void SCR_DisplayTicRate(void)
|
|||
ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));*/
|
||||
|
||||
// draw "FPS"
|
||||
V_DrawFixedPatch(306<<FRACBITS, 183<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, framecounter, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE));
|
||||
V_DrawFixedPatch(306<<FRACBITS, 183<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, framecounter, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE));
|
||||
// draw total frame:
|
||||
V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, TICRATE, ticcntcolor);
|
||||
V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, TICRATE, ticcntcolor);
|
||||
// draw "/"
|
||||
V_DrawFixedPatch(306<<FRACBITS, 190<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, frameslash, ticcntcolor);
|
||||
V_DrawFixedPatch(306<<FRACBITS, 190<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, frameslash, ticcntcolor);
|
||||
// draw our actual framerate
|
||||
V_DrawPingNum(306, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, totaltics, ticcntcolor);
|
||||
V_DrawPingNum(306, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, totaltics, ticcntcolor);
|
||||
|
||||
|
||||
lasttic = ontic;
|
||||
|
|
@ -448,6 +448,6 @@ void SCR_DisplayLocalPing(void)
|
|||
if (cv_showping.value == 1 || (cv_showping.value == 2 && ping > 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -3177,11 +3183,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();
|
||||
|
|
|
|||
|
|
@ -1377,11 +1377,17 @@ 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 || ! server_lagless ))
|
||||
{
|
||||
SCR_DisplayLocalPing();
|
||||
}
|
||||
}
|
||||
|
||||
if (rendermode == render_soft && screens[0])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{"bsnipe", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Banana sniping
|
||||
{"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // :shitsfree:
|
||||
{"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Debug notification
|
||||
|
|
|
|||
|
|
@ -890,6 +890,7 @@ typedef enum
|
|||
sfx_chain,
|
||||
sfx_mkuma,
|
||||
sfx_toada,
|
||||
sfx_bhurry,
|
||||
sfx_bsnipe,
|
||||
sfx_itfree,
|
||||
sfx_dbgsal,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
103
src/v_video.c
103
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)<<FF_TRANSSHIFT) + color*256)); // Else, do TRANSMAP** fade.
|
||||
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
UINT8 *buf = screens[0];
|
||||
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
UINT8 *buf = screens[0];
|
||||
|
||||
// heavily simplified -- we don't need to know x or y
|
||||
// position when we're doing a full screen fade
|
||||
for (; buf < deststop; ++buf)
|
||||
*buf = fadetable[*buf];
|
||||
}
|
||||
// heavily simplified -- we don't need to know x or y
|
||||
// position when we're doing a full screen fade
|
||||
for (; buf < deststop; ++buf)
|
||||
*buf = fadetable[*buf];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Fade the screen buffer, using a custom COLORMAP lump.
|
||||
// Split from V_DrawFadeScreen, because that function has
|
||||
// WAY too many options piled on top of it as is. :V
|
||||
//
|
||||
void V_DrawCustomFadeScreen(const char *lump, UINT8 strength)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft && rendermode != render_none)
|
||||
{
|
||||
//HWR_DrawCustomFadeScreen(color, strength);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
lumpnum_t lumpnum = LUMPERROR;
|
||||
lighttable_t *clm = NULL;
|
||||
|
||||
if (lump != NULL)
|
||||
lumpnum = W_GetNumForName(lump);
|
||||
else
|
||||
return;
|
||||
|
||||
if (lumpnum != LUMPERROR)
|
||||
{
|
||||
clm = Z_MallocAlign((256 * 32), PU_STATIC, NULL, 8);
|
||||
W_ReadLump(lumpnum, clm);
|
||||
|
||||
if (clm != NULL)
|
||||
{
|
||||
const UINT8 *fadetable = ((UINT8 *)clm + strength*256);
|
||||
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
UINT8 *buf = screens[0];
|
||||
|
||||
// heavily simplified -- we don't need to know x or y
|
||||
// position when we're doing a full screen fade
|
||||
for (; buf < deststop; ++buf)
|
||||
*buf = fadetable[*buf];
|
||||
|
||||
Z_Free(clm);
|
||||
clm = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Simple translucency with one color, over a set number of lines starting from the top.
|
||||
|
|
@ -1332,6 +1379,34 @@ void V_DrawFadeConsBack(INT32 plines)
|
|||
*buf = consolebgmap[*buf];
|
||||
}
|
||||
|
||||
//
|
||||
// Invert the entire screen, for Encore fades
|
||||
//
|
||||
void V_EncoreInvertScreen(void)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft && rendermode != render_none)
|
||||
{
|
||||
//HWR_EncoreInvertScreen();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
UINT8 *buf = screens[0];
|
||||
|
||||
for (; buf < deststop; ++buf)
|
||||
{
|
||||
*buf = NearestColor(
|
||||
256 - pLocalPalette[*buf].s.red,
|
||||
256 - pLocalPalette[*buf].s.green,
|
||||
256 - pLocalPalette[*buf].s.blue
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gets string colormap, used for 0x80 color codes
|
||||
//
|
||||
UINT8 *V_GetStringColormap(INT32 colorflags)
|
||||
|
|
|
|||
|
|
@ -158,8 +158,9 @@ void V_DrawVhsEffect(boolean rewind);
|
|||
|
||||
// fade down the screen buffer before drawing the menu over
|
||||
void V_DrawFadeScreen(UINT16 color, UINT8 strength);
|
||||
|
||||
void V_DrawCustomFadeScreen(const char *lump, UINT8 strength);
|
||||
void V_DrawFadeConsBack(INT32 plines);
|
||||
void V_EncoreInvertScreen(void);
|
||||
|
||||
// draw a single character
|
||||
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed);
|
||||
|
|
|
|||
301
src/y_inter.c
301
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
|
||||
|
||||
|
|
@ -90,7 +91,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
|
||||
|
|
@ -110,6 +111,7 @@ static boolean usetile;
|
|||
boolean usebuffer = false;
|
||||
static boolean useinterpic;
|
||||
static INT32 timer;
|
||||
static INT32 powertype = PWRLV_DISABLED;
|
||||
|
||||
static INT32 intertic;
|
||||
static INT32 endtic = -1;
|
||||
|
|
@ -193,11 +195,13 @@ 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 || (score - increase) > data.match.val[data.match.numplayers]))
|
||||
return;
|
||||
|
||||
data.match.val[data.match.numplayers] = (players[i].score - increase);
|
||||
data.match.val[data.match.numplayers] = (score - increase);
|
||||
data.match.num[data.match.numplayers] = i;
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +209,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)
|
||||
|
|
@ -257,14 +261,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++;
|
||||
}
|
||||
|
|
@ -276,8 +283,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])
|
||||
|
|
@ -299,9 +304,10 @@ 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];
|
||||
}
|
||||
|
||||
|
|
@ -429,9 +435,10 @@ 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 = "RANK";
|
||||
timeheader = "PWR.LV";
|
||||
else
|
||||
timeheader = (intertype == int_race ? "TIME" : "SCORE");
|
||||
|
||||
|
|
@ -486,28 +493,61 @@ 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)
|
||||
{
|
||||
if (data.match.increase[data.match.num[i]] != UINT8_MAX)
|
||||
if (!clientpowerlevels[data.match.num[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)
|
||||
{
|
||||
snprintf(strtime, sizeof strtime, "(%d)", data.match.increase[data.match.num[i]]);
|
||||
|
||||
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||
V_DrawRightAlignedThinString(x+135+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||
else
|
||||
V_DrawRightAlignedString(x+120+gutter, y, 0, strtime);
|
||||
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||
V_DrawRightAlignedThinString(x+133+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||
else
|
||||
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]);
|
||||
|
||||
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||
else
|
||||
|
|
@ -591,9 +631,14 @@ dotimer:
|
|||
break;
|
||||
}
|
||||
|
||||
// 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) // Make it obvious that scrambling is happening next round. (OR NOT, I GUESS)
|
||||
//{
|
||||
/*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[1+speedscramble].strvalue));
|
||||
//}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -676,13 +721,46 @@ 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++;
|
||||
data.match.jitter[data.match.num[q]] = 1;
|
||||
if (--data.match.increase[data.match.num[q]])
|
||||
kaching = false;
|
||||
|
||||
if (powertype != -1)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
// Basic bitch points
|
||||
if (data.match.increase[data.match.num[q]])
|
||||
{
|
||||
if (--data.match.increase[data.match.num[q]])
|
||||
kaching = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r)
|
||||
|
|
@ -782,6 +860,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
|
||||
//
|
||||
|
|
@ -796,6 +1021,17 @@ void Y_StartIntermission(void)
|
|||
I_Error("endtic is dirty");
|
||||
#endif
|
||||
|
||||
// set player Power Level type
|
||||
powertype = PWRLV_DISABLED;
|
||||
|
||||
if (netgame && cv_kartusepwrlv.value)
|
||||
{
|
||||
if (G_RaceGametype())
|
||||
powertype = PWRLV_RACE;
|
||||
else if (G_BattleGametype())
|
||||
powertype = PWRLV_BATTLE;
|
||||
}
|
||||
|
||||
if (!multiplayer)
|
||||
{
|
||||
timer = 0;
|
||||
|
|
@ -872,6 +1108,9 @@ void Y_StartIntermission(void)
|
|||
break;
|
||||
}
|
||||
|
||||
if (powertype != PWRLV_DISABLED)
|
||||
K_UpdatePowerLevels();
|
||||
|
||||
//if (intertype == int_race || intertype == int_match)
|
||||
{
|
||||
//bgtile = W_CachePatchName("SRB2BACK", PU_STATIC);
|
||||
|
|
|
|||
|
|
@ -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<<sizeof(size_t))*2;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue