Merge branch 'master' of git.magicalgirl.moe:KartKrew/Kart into v2-master

This commit is contained in:
Latapostrophe 2019-10-02 19:18:42 +02:00
commit f3bcc989df
44 changed files with 1656 additions and 808 deletions

View file

@ -17,7 +17,7 @@ set(SRB2_ASSET_HASHED
gfx.pk3;\ gfx.pk3;\
textures.pk3;\ textures.pk3;\
chars.pk3;\ chars.pk3;\
maps.wad;\ maps.pk3;\
patch.pk3" patch.pk3"
CACHE STRING "Asset filenames to apply MD5 checks. No spaces between entries!" CACHE STRING "Asset filenames to apply MD5 checks. No spaces between entries!"
) )

View file

@ -902,7 +902,10 @@ static void COM_Add_f(void)
return; return;
} }
CV_AddValue(cvar, atoi(COM_Argv(2))); if (( cvar->flags & CV_FLOAT ))
CV_Set(cvar, va("%f", FIXED_TO_FLOAT (cvar->value) + atof(COM_Argv(2))));
else
CV_AddValue(cvar, atoi(COM_Argv(2)));
} }
// ========================================================================= // =========================================================================

View file

@ -15,7 +15,7 @@
#define ASSET_HASH_GFX_PK3 "${SRB2_ASSET_gfx.pk3_HASH}" #define ASSET_HASH_GFX_PK3 "${SRB2_ASSET_gfx.pk3_HASH}"
#define ASSET_HASH_TEXTURES_PK3 "${SRB2_ASSET_textures.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_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 #ifdef USE_PATCH_FILE
#define ASSET_HASH_PATCH_PK3 "${SRB2_ASSET_patch.pk3_HASH}" #define ASSET_HASH_PATCH_PK3 "${SRB2_ASSET_patch.pk3_HASH}"
#endif #endif
@ -36,7 +36,7 @@
#define ASSET_HASH_GFX_PK3 "00000000000000000000000000000000" #define ASSET_HASH_GFX_PK3 "00000000000000000000000000000000"
#define ASSET_HASH_TEXTURES_PK3 "00000000000000000000000000000000" #define ASSET_HASH_TEXTURES_PK3 "00000000000000000000000000000000"
#define ASSET_HASH_CHARS_PK3 "00000000000000000000000000000000" #define ASSET_HASH_CHARS_PK3 "00000000000000000000000000000000"
#define ASSET_HASH_MAPS_WAD "00000000000000000000000000000000" #define ASSET_HASH_MAPS_PK3 "00000000000000000000000000000000"
#ifdef USE_PATCH_FILE #ifdef USE_PATCH_FILE
#define ASSET_HASH_PATCH_PK3 "00000000000000000000000000000000" #define ASSET_HASH_PATCH_PK3 "00000000000000000000000000000000"
#endif #endif

View file

@ -1428,8 +1428,14 @@ static void SV_SendPlayerInfo(INT32 node)
UINT8 i; UINT8 i;
netbuffer->packettype = PT_PLAYERINFO; netbuffer->packettype = PT_PLAYERINFO;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MSCOMPAT_MAXPLAYERS; i++)
{ {
if (i >= MAXPLAYERS)
{
netbuffer->u.playerinfo[i].node = 255;
continue;
}
if (!playeringame[i]) if (!playeringame[i])
{ {
netbuffer->u.playerinfo[i].node = 255; // This slot is empty. netbuffer->u.playerinfo[i].node = 255; // This slot is empty.
@ -1477,7 +1483,7 @@ static void SV_SendPlayerInfo(INT32 node)
netbuffer->u.playerinfo[i].data |= 0x80; netbuffer->u.playerinfo[i].data |= 0x80;
} }
HSendPacket(node, false, 0, sizeof(plrinfo) * MAXPLAYERS); HSendPacket(node, false, 0, sizeof(plrinfo) * MSCOMPAT_MAXPLAYERS);
} }
/** Sends a PT_SERVERCFG packet /** Sends a PT_SERVERCFG packet

View file

@ -468,7 +468,7 @@ typedef struct
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...) serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
askinfo_pak askinfo; // 61 bytes askinfo_pak askinfo; // 61 bytes
msaskinfo_pak msaskinfo; // 22 bytes msaskinfo_pak msaskinfo; // 22 bytes
plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?) plrinfo playerinfo[MSCOMPAT_MAXPLAYERS];// 576 bytes(?)
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?) plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
INT32 filesneedednum; // 4 bytes INT32 filesneedednum; // 4 bytes
filesneededconfig_pak filesneededcfg; // ??? bytes filesneededconfig_pak filesneededcfg; // ??? bytes

View file

@ -447,7 +447,7 @@ static void D_Display(void)
{ {
if (i > 0) // Splitscreen-specific if (i > 0) // Splitscreen-specific
{ {
switch (i) switch (i)
{ {
case 1: case 1:
if (splitscreen > 1) if (splitscreen > 1)
@ -896,11 +896,18 @@ static void IdentifyVersion(void)
D_AddFile(va(pandf,srb2waddir,"gfx.pk3"), startupwadfiles); D_AddFile(va(pandf,srb2waddir,"gfx.pk3"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"textures.pk3"), startupwadfiles); D_AddFile(va(pandf,srb2waddir,"textures.pk3"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"chars.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 #ifdef USE_PATCH_FILE
D_AddFile(va(pandf,srb2waddir,"patch.pk3"), startupwadfiles); D_AddFile(va(pandf,srb2waddir,"patch.pk3"), startupwadfiles);
#endif #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) #if !defined (HAVE_SDL) || defined (HAVE_MIXER)
#define MUSICTEST(str) \ #define MUSICTEST(str) \
{\ {\
@ -915,6 +922,7 @@ static void IdentifyVersion(void)
MUSICTEST("music.wad") MUSICTEST("music.wad")
#undef MUSICTEST #undef MUSICTEST
#endif #endif
#endif
} }
/* ======================================================================== */ /* ======================================================================== */
@ -1182,12 +1190,12 @@ void D_SRB2Main(void)
M_InitCharacterTables(); M_InitCharacterTables();
// load wad, including the main wad file // 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)) if (!W_InitMultipleFiles(startupwadfiles, false))
#ifdef _DEBUG #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 #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 #endif
D_CleanFile(startupwadfiles); D_CleanFile(startupwadfiles);
@ -1200,7 +1208,7 @@ void D_SRB2Main(void)
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_PK3); // gfx.pk3 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_TEXTURES_PK3); // textures.pk3
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_PK3); // chars.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 #ifdef USE_PATCH_FILE
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_PK3); // patch.pk3 mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_PK3); // patch.pk3
#endif #endif
@ -1208,7 +1216,7 @@ void D_SRB2Main(void)
mainwads++; // gfx.pk3 mainwads++; // gfx.pk3
mainwads++; // textures.pk3 mainwads++; // textures.pk3
mainwads++; // chars.pk3 mainwads++; // chars.pk3
mainwads++; // maps.wad mainwads++; // maps.pk3
#ifdef USE_PATCH_FILE #ifdef USE_PATCH_FILE
mainwads++; // patch.pk3 mainwads++; // patch.pk3
#endif #endif
@ -1241,8 +1249,9 @@ void D_SRB2Main(void)
} }
} }
CONS_Printf("W_InitMultipleFiles(): Adding external PWADs.\n");
if (!W_InitMultipleFiles(startuppwads, true)) 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); D_CleanFile(startuppwads);
// //

View file

@ -2041,7 +2041,7 @@ static void Command_View_f(void)
return; return;
} }
displayplayerp = &displayplayers[viewnum]; displayplayerp = &displayplayers[viewnum-1];
if (COM_Argc() > 1)/* switch to player */ if (COM_Argc() > 1)/* switch to player */
{ {

View file

@ -130,7 +130,8 @@ UINT8 *PutFileNeeded(UINT16 firstfile)
nameonly(strcpy(wadfilename, wadfiles[i]->filename)); nameonly(strcpy(wadfilename, wadfiles[i]->filename));
if (p + 1 + 4 + strlen(wadfilename) + 16 > p_start + MAXFILENEEDED) // Look below at the WRITE macros to understand what these numbers mean.
if (p + 1 + 4 + min(strlen(wadfilename) + 1, MAX_WADPATH) + 16 > p_start + MAXFILENEEDED)
{ {
// Too many files to send all at once // Too many files to send all at once
if (netbuffer->packettype == PT_MOREFILESNEEDED) if (netbuffer->packettype == PT_MOREFILESNEEDED)

View file

@ -327,6 +327,9 @@ typedef enum
k_jawztargetdelay, // Delay for Jawz target switching, to make it less twitchy k_jawztargetdelay, // Delay for Jawz target switching, to make it less twitchy
k_spectatewait, // How long have you been waiting as a spectator k_spectatewait, // How long have you been waiting as a spectator
k_growcancel, // Hold the item button down to cancel Grow k_growcancel, // Hold the item button down to cancel Grow
k_tiregrease, // Reduced friction timer after hitting a horizontal spring
k_springstars, // Spawn stars around a player when they hit a spring
k_springcolor, // Color of spring stars
NUMKARTSTUFF NUMKARTSTUFF
} kartstufftype_t; } kartstufftype_t;

View file

@ -1230,8 +1230,9 @@ static void readlevelheader(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "WEATHER")) else if (fastcmp(word, "WEATHER"))
mapheaderinfo[num-1]->weather = (UINT8)get_number(word2); mapheaderinfo[num-1]->weather = (UINT8)get_number(word2);
else if (fastcmp(word, "SKYNUM")) else if (fastcmp(word, "SKYTEXTURE"))
mapheaderinfo[num-1]->skynum = (INT16)i; deh_strlcpy(mapheaderinfo[num-1]->skytexture, word2,
sizeof(mapheaderinfo[num-1]->skytexture), va("Level header %d: sky texture", num));
else if (fastcmp(word, "INTERSCREEN")) else if (fastcmp(word, "INTERSCREEN"))
strncpy(mapheaderinfo[num-1]->interscreen, word2, 8); strncpy(mapheaderinfo[num-1]->interscreen, word2, 8);
else if (fastcmp(word, "PRECUTSCENENUM")) else if (fastcmp(word, "PRECUTSCENENUM"))
@ -5609,44 +5610,77 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_RBIRD2", "S_RBIRD2",
"S_RBIRD3", "S_RBIRD3",
"S_YELLOWSPRING", // Yellow Spring
"S_YELLOWSPRING1",
"S_YELLOWSPRING2", "S_YELLOWSPRING2",
"S_YELLOWSPRING3", "S_YELLOWSPRING3",
"S_YELLOWSPRING4", "S_YELLOWSPRING4",
"S_YELLOWSPRING5",
"S_REDSPRING", // Red Spring
"S_REDSPRING1",
"S_REDSPRING2", "S_REDSPRING2",
"S_REDSPRING3", "S_REDSPRING3",
"S_REDSPRING4", "S_REDSPRING4",
"S_REDSPRING5",
// Blue Springs // Blue Spring
"S_BLUESPRING", "S_BLUESPRING1",
"S_BLUESPRING2", "S_BLUESPRING2",
"S_BLUESPRING3", "S_BLUESPRING3",
"S_BLUESPRING4", "S_BLUESPRING4",
"S_BLUESPRING5",
// Grey Spring
"S_GREYSPRING1",
"S_GREYSPRING2",
"S_GREYSPRING3",
"S_GREYSPRING4",
// Yellow Diagonal Spring // Yellow Diagonal Spring
"S_YDIAG1", "S_YDIAG1",
"S_YDIAG2", "S_YDIAG2",
"S_YDIAG3", "S_YDIAG3",
"S_YDIAG4", "S_YDIAG4",
"S_YDIAG5",
"S_YDIAG6",
"S_YDIAG7",
"S_YDIAG8",
// Red Diagonal Spring // Red Diagonal Spring
"S_RDIAG1", "S_RDIAG1",
"S_RDIAG2", "S_RDIAG2",
"S_RDIAG3", "S_RDIAG3",
"S_RDIAG4", "S_RDIAG4",
"S_RDIAG5",
"S_RDIAG6", // Blue Diagonal Spring
"S_RDIAG7", "S_BDIAG1",
"S_RDIAG8", "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 // Rain
"S_RAIN1", "S_RAIN1",
@ -6271,26 +6305,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_SRB1_GENREX1", "S_SRB1_GENREX1",
"S_SRB1_GENREX2", "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 //{ Random Item Box
"S_RANDOMITEM1", "S_RANDOMITEM1",
"S_RANDOMITEM2", "S_RANDOMITEM2",
@ -7199,6 +7213,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_DRAFTDUST4", "S_DRAFTDUST4",
"S_DRAFTDUST5", "S_DRAFTDUST5",
"S_TIREGREASE",
#ifdef SEENAMES #ifdef SEENAMES
"S_NAMECHECK", "S_NAMECHECK",
#endif #endif
@ -7328,11 +7344,18 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
// Springs and others // Springs and others
"MT_FAN", "MT_FAN",
"MT_STEAM", // Steam riser "MT_STEAM", // Steam riser
"MT_BLUESPRING",
"MT_YELLOWSPRING", "MT_YELLOWSPRING",
"MT_REDSPRING", "MT_REDSPRING",
"MT_BLUESPRING",
"MT_GREYSPRING",
"MT_YELLOWDIAG", // Yellow Diagonal Spring "MT_YELLOWDIAG", // Yellow Diagonal Spring
"MT_REDDIAG", // Red 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 // Interactive Objects
"MT_BUBBLES", // Bubble source "MT_BUBBLES", // Bubble source
@ -7714,9 +7737,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_SRB1_GENREX", "MT_SRB1_GENREX",
// SRB2kart // SRB2kart
"MT_GRAYSPRING",
"MT_INVISSPRING",
"MT_BLUEDIAG",
"MT_RANDOMITEM", "MT_RANDOMITEM",
"MT_RANDOMITEMPOP", "MT_RANDOMITEMPOP",
"MT_FLOATINGITEM", "MT_FLOATINGITEM",
@ -7987,6 +8007,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_KARMAFIREWORK", "MT_KARMAFIREWORK",
"MT_RINGSPARKS", "MT_RINGSPARKS",
"MT_DRAFTDUST", "MT_DRAFTDUST",
"MT_TIREGREASE",
#ifdef SEENAMES #ifdef SEENAMES
"MT_NAMECHECK", "MT_NAMECHECK",
@ -8473,7 +8494,10 @@ static const char *const KARTSTUFF_LIST[] = {
"GETSPARKS", "GETSPARKS",
"JAWZTARGETDELAY", "JAWZTARGETDELAY",
"SPECTATEWAIT", "SPECTATEWAIT",
"GROWCANCEL" "GROWCANCEL",
"TIREGREASE",
"SPRINGSTARS",
"SPRINGCOLOR"
}; };
#endif #endif
@ -9903,11 +9927,11 @@ static inline int lib_getenum(lua_State *L)
} else if (fastcmp(word,"globalweather")) { } else if (fastcmp(word,"globalweather")) {
lua_pushinteger(L, globalweather); lua_pushinteger(L, globalweather);
return 1; return 1;
} else if (fastcmp(word,"levelskynum")) { } else if (fastcmp(word,"levelskytexture")) {
lua_pushinteger(L, levelskynum); lua_pushstring(L, levelskytexture);
return 1; return 1;
} else if (fastcmp(word,"globallevelskynum")) { } else if (fastcmp(word,"globallevelskytexture")) {
lua_pushinteger(L, globallevelskynum); lua_pushstring(L, globallevelskytexture);
return 1; return 1;
} else if (fastcmp(word,"mapmusname")) { } else if (fastcmp(word,"mapmusname")) {
lua_pushstring(L, mapmusname); lua_pushstring(L, mapmusname);

View file

@ -249,6 +249,9 @@ extern FILE *logstream;
#define PLAYERSMASK (MAXPLAYERS-1) #define PLAYERSMASK (MAXPLAYERS-1)
#define MAXPLAYERNAME 21 #define MAXPLAYERNAME 21
// Master Server compatibility ONLY
#define MSCOMPAT_MAXPLAYERS (32)
typedef enum typedef enum
{ {
SKINCOLOR_NONE = 0, SKINCOLOR_NONE = 0,

View file

@ -227,7 +227,7 @@ typedef struct
UINT32 muspos; ///< Music position to jump to. UINT32 muspos; ///< Music position to jump to.
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. 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. 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_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_scaley; ///< Skybox Y axis scale.
INT16 skybox_scalez; ///< Skybox Z axis scale. INT16 skybox_scalez; ///< Skybox Z axis scale.
@ -435,6 +435,7 @@ extern INT32 sneakertime;
extern INT32 itemtime; extern INT32 itemtime;
extern INT32 comebacktime; extern INT32 comebacktime;
extern INT32 bumptime; extern INT32 bumptime;
extern INT32 greasetics;
extern INT32 wipeoutslowtime; extern INT32 wipeoutslowtime;
extern INT32 wantedreduce; extern INT32 wantedreduce;
extern INT32 wantedfrequency; extern INT32 wantedfrequency;

View file

@ -216,6 +216,7 @@ INT32 sneakertime = TICRATE + (TICRATE/3);
INT32 itemtime = 8*TICRATE; INT32 itemtime = 8*TICRATE;
INT32 comebacktime = 10*TICRATE; INT32 comebacktime = 10*TICRATE;
INT32 bumptime = 6; INT32 bumptime = 6;
INT32 greasetics = 3*TICRATE;
INT32 wipeoutslowtime = 20; INT32 wipeoutslowtime = 20;
INT32 wantedreduce = 5*TICRATE; INT32 wantedreduce = 5*TICRATE;
INT32 wantedfrequency = 10*TICRATE; INT32 wantedfrequency = 10*TICRATE;
@ -3642,7 +3643,7 @@ tryagain:
void G_AddMapToBuffer(INT16 map) 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. // Add the map to the buffer.
for (bufx = NUMMAPS-1; bufx > 0; bufx--) for (bufx = NUMMAPS-1; bufx > 0; bufx--)
@ -6483,10 +6484,10 @@ void G_WriteStanding(UINT8 ranking, char *name, INT32 skinnum, UINT8 color, UINT
{ {
char temp[16]; char temp[16];
if (demoinfo_p && (UINT32)(*demoinfo_p) == 0) if (demoinfo_p && *(UINT32 *)demoinfo_p == 0)
{ {
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
WRITEUINT32(demoinfo_p, demo_p - demobuffer); *(UINT32 *)demoinfo_p = demo_p - demobuffer;
} }
WRITEUINT8(demo_p, DW_STANDING); WRITEUINT8(demo_p, DW_STANDING);
@ -8178,16 +8179,17 @@ boolean G_CheckDemoStatus(void)
void G_SaveDemo(void) void G_SaveDemo(void)
{ {
UINT8 *p = demobuffer+16; // checksum position UINT8 *p = demobuffer+16; // after version
UINT32 length;
#ifdef NOMD5 #ifdef NOMD5
UINT8 i; UINT8 i;
#endif #endif
// Ensure extrainfo pointer is always available, even if no info is present. // Ensure extrainfo pointer is always available, even if no info is present.
if (demoinfo_p && (UINT32)(*demoinfo_p) == 0) if (demoinfo_p && *(UINT32 *)demoinfo_p == 0)
{ {
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
WRITEUINT32(demoinfo_p, (UINT32)(demo_p - demobuffer)); *(UINT32 *)demoinfo_p = demo_p - demobuffer;
} }
WRITEUINT8(demo_p, DW_END); // Mark end of demo extra data. WRITEUINT8(demo_p, DW_END); // Mark end of demo extra data.
@ -8233,12 +8235,14 @@ void G_SaveDemo(void)
sprintf(writepoint, "%s.lmp", demo_slug); sprintf(writepoint, "%s.lmp", demo_slug);
} }
length = *(UINT32 *)demoinfo_p;
WRITEUINT32(demoinfo_p, length);
#ifdef NOMD5 #ifdef NOMD5
for (i = 0; i < 16; i++, p++) for (i = 0; i < 16; i++, p++)
*p = M_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. *p = M_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
#else #else
// Make a checksum of everything after the checksum in the file up to the end of the standard data. Extrainfo is freely modifiable. // Make a checksum of everything after the checksum in the file up to the end of the standard data. Extrainfo is freely modifiable.
md5_buffer((char *)p+16, (demobuffer + (UINT32)*demoinfo_p) - (p+16), p); md5_buffer((char *)p+16, (demobuffer + length) - (p+16), p);
#endif #endif

View file

@ -1319,7 +1319,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
// HWR_DrawSkyWalls // HWR_DrawSkyWalls
// Draw walls into the depth buffer so that anything behind is culled properly // Draw walls into the depth buffer so that anything behind is culled properly
static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top) static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf)
{ {
HWD.pfnSetTexture(NULL); HWD.pfnSetTexture(NULL);
// no texture // no texture
@ -1327,9 +1327,6 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b
wallVerts[0].t = wallVerts[1].t = 0; wallVerts[0].t = wallVerts[1].t = 0;
wallVerts[0].s = wallVerts[3].s = 0; wallVerts[0].s = wallVerts[3].s = 0;
wallVerts[2].s = wallVerts[1].s = 0; wallVerts[2].s = wallVerts[1].s = 0;
// set top/bottom coords
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(top); // No real way to find the correct height of this
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(bottom); // worldlow/bottom because it needs to cover up the lower thok barrier wall
HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_Clip|PF_NoTexture, 255, NULL); HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_Clip|PF_NoTexture, 255, NULL);
// PF_Invisible so it's not drawn into the colour buffer // PF_Invisible so it's not drawn into the colour buffer
// PF_NoTexture for no texture // PF_NoTexture for no texture
@ -1462,6 +1459,111 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
worldlow = gr_backsector->floorheight; worldlow = gr_backsector->floorheight;
#endif #endif
// Sky culling
if (!gr_curline->polyseg) // Don't do it for polyobjects
{
// Sky Ceilings
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX);
if (gr_frontsector->ceilingpic == skyflatnum)
{
if (gr_backsector->ceilingpic == skyflatnum)
{
// Both front and back sectors are sky, needs skywall from the frontsector's ceiling, but only if the
// backsector is lower
if ((worldhigh <= worldtop)
#ifdef ESLOPE
&& (worldhighslope <= worldtopslope)
#endif
)
{
#ifdef ESLOPE
wallVerts[0].y = FIXED_TO_FLOAT(worldhigh);
wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope);
#else
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldhigh);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
else
{
// Only the frontsector is sky, just draw a skywall from the front ceiling
#ifdef ESLOPE
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
#else
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
else if (gr_backsector->ceilingpic == skyflatnum)
{
// Only the backsector is sky, just draw a skywall from the front ceiling
#ifdef ESLOPE
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
#else
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
// Sky Floors
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN);
if (gr_frontsector->floorpic == skyflatnum)
{
if (gr_backsector->floorpic == skyflatnum)
{
// Both front and back sectors are sky, needs skywall from the backsector's floor, but only if the
// it's higher, also needs to check for bottomtexture as the floors don't usually move down
// when both sides are sky floors
if ((worldlow >= worldbottom)
#ifdef ESLOPE
&& (worldlowslope >= worldbottomslope)
#endif
&& !(gr_sidedef->bottomtexture))
{
#ifdef ESLOPE
wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope);
#else
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldlow);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
else
{
// Only the backsector has sky, just draw a skywall from the back floor
#ifdef ESLOPE
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
#else
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldbottom);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
else if ((gr_backsector->floorpic == skyflatnum) && !(gr_sidedef->bottomtexture))
{
// Only the backsector has sky, just draw a skywall from the back floor if there's no bottomtexture
#ifdef ESLOPE
wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope);
#else
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldlow);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
// hack to allow height changes in outdoor areas // hack to allow height changes in outdoor areas
// This is what gets rid of the upper textures if there should be sky // This is what gets rid of the upper textures if there should be sky
if (gr_frontsector->ceilingpic == skyflatnum && if (gr_frontsector->ceilingpic == skyflatnum &&
@ -1914,85 +2016,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
Surf.FlatColor.rgba = 0xffffffff; Surf.FlatColor.rgba = 0xffffffff;
}*/ }*/
} }
// Isn't this just the most lovely mess
if (!gr_curline->polyseg) // Don't do it for polyobjects
{
if (gr_frontsector->ceilingpic == skyflatnum || gr_backsector->ceilingpic == skyflatnum)
{
fixed_t depthwallheight;
if (!gr_sidedef->toptexture || (gr_frontsector->ceilingpic == skyflatnum && gr_backsector->ceilingpic == skyflatnum)) // when both sectors are sky, the top texture isn't drawn
depthwallheight = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight;
else
depthwallheight = gr_frontsector->ceilingheight > gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight;
if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier
{
if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier
{
if (!gr_sidedef->bottomtexture) // Only extend further down if there's no texture
HWR_DrawSkyWall(wallVerts, &Surf, worldbottom < worldlow ? worldbottom : worldlow, INT32_MAX);
else
HWR_DrawSkyWall(wallVerts, &Surf, worldbottom > worldlow ? worldbottom : worldlow, INT32_MAX);
}
// behind sector is not a thok barrier
else if (gr_backsector->ceilingheight <= gr_frontsector->ceilingheight) // behind sector ceiling is lower or equal to current sector
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
// gr_front/backsector heights need to be used here because of the worldtop being set to worldhigh earlier on
}
else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not
{
if (gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier ceiling height is equal to or greater than current sector ceiling height
|| gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier ceiling height is equal to or less than current sector floor height
|| gr_backsector->ceilingpic != skyflatnum) // thok barrier is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
}
else // neither sectors are thok barriers
{
if ((gr_backsector->ceilingheight < gr_frontsector->ceilingheight && !gr_sidedef->toptexture) // no top texture and sector behind is lower
|| gr_backsector->ceilingpic != skyflatnum) // behind sector is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
}
}
// And now for sky floors!
if (gr_frontsector->floorpic == skyflatnum || gr_backsector->floorpic == skyflatnum)
{
fixed_t depthwallheight;
if (!gr_sidedef->bottomtexture)
depthwallheight = worldbottom > worldlow ? worldbottom : worldlow;
else
depthwallheight = worldbottom < worldlow ? worldbottom : worldlow;
if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier
{
if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier
{
if (!gr_sidedef->toptexture) // Only extend up if there's no texture
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop > worldhigh ? worldtop : worldhigh);
else
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop < worldhigh ? worldtop : worldhigh);
}
// behind sector is not a thok barrier
else if (gr_backsector->floorheight >= gr_frontsector->floorheight) // behind sector floor is greater or equal to current sector
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
}
else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not
{
if (gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier floor height is equal to or less than current sector floor height
|| gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier floor height is equal to or greater than current sector ceiling height
|| gr_backsector->floorpic != skyflatnum) // thok barrier is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
}
else // neither sectors are thok barriers
{
if ((gr_backsector->floorheight > gr_frontsector->floorheight && !gr_sidedef->bottomtexture) // no bottom texture and sector behind is higher
|| gr_backsector->floorpic != skyflatnum) // behind sector is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
}
}
}
} }
else else
{ {
@ -2060,13 +2083,52 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
} }
} }
else
{
#ifdef ESLOPE
//Set textures properly on single sided walls that are sloped
wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
wallVerts[0].y = FIXED_TO_FLOAT(worldbottom);
wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
#else
// set top/bottom coords
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldbottom);
#endif
// When there's no midtexture, draw a skywall to prevent rendering behind it
HWR_DrawSkyWall(wallVerts, &Surf);
}
// Single sided lines are simple for skywalls, just need to draw from the top or bottom of the sector if there's
// a sky flat
if (!gr_curline->polyseg) if (!gr_curline->polyseg)
{ {
if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector
HWR_DrawSkyWall(wallVerts, &Surf, worldtop, INT32_MAX); {
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX);
#ifdef ESLOPE
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
#else
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
if (gr_frontsector->floorpic == skyflatnum) if (gr_frontsector->floorpic == skyflatnum)
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldbottom); {
#ifdef ESLOPE
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
#else
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldbottom);
#endif
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN);
HWR_DrawSkyWall(wallVerts, &Surf);
}
} }
} }
@ -2381,7 +2443,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
// e6y: Check whether the player can look beyond this line // e6y: Check whether the player can look beyond this line
// //
#ifdef NEWCLIP #ifdef NEWCLIP
boolean checkforemptylines = true; static boolean checkforemptylines = true;
// Don't modify anything here, just check // Don't modify anything here, just check
// Kalaron: Modified for sloped linedefs // Kalaron: Modified for sloped linedefs
static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector) static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector)
@ -2421,62 +2483,47 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks
backc1 = backc2 = abacksector->ceilingheight; backc1 = backc2 = abacksector->ceilingheight;
} }
// now check for closed sectors! if (viewsector != abacksector && viewsector != afrontsector)
if (backc1 <= frontf1 && backc2 <= frontf2)
{ {
checkforemptylines = false; boolean mydoorclosed = false; // My door? Closed!? (doorclosed is actually otherwise unused in openGL)
if (!seg->sidedef->toptexture)
return false;
if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) // If the sector behind the line blocks all kinds of view past it
return false; // (back ceiling is lower than close floor, or back floor is higher than close ceiling)
if ((backc1 <= frontf1 && backc2 <= frontf2)
return true; || (backf1 >= frontc1 && backf2 >= frontc2))
}
if (backf1 >= frontc1 && backf2 >= frontc2)
{
checkforemptylines = false;
if (!seg->sidedef->bottomtexture)
return false;
// properly render skies (consider door "open" if both floors are sky):
if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
return false;
return true;
}
if (backc1 <= backf1 && backc2 <= backf2)
{
checkforemptylines = false;
// preserve a kind of transparent door/lift special effect:
if (backc1 < frontc1 || backc2 < frontc2)
{
if (!seg->sidedef->toptexture)
return false;
}
if (backf1 > frontf1 || backf2 > frontf2)
{
if (!seg->sidedef->bottomtexture)
return false;
}
if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
return false;
if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum)
return false;
return true;
}
if (backc1 != frontc1 || backc2 != frontc2
|| backf1 != frontf1 || backf2 != frontf2)
{ {
checkforemptylines = false; checkforemptylines = false;
return false; return true;
} }
// The door is closed if:
// backsector is 0 height or less and
// back ceiling is higher than close ceiling or we need to render a top texture and
// back floor is lower than close floor or we need to render a bottom texture and
// neither front or back sectors are using the sky ceiling
mydoorclosed = (backc1 <= backf1 && backc2 <= backf2
&& ((backc1 >= frontc1 && backc2 >= frontc2) || seg->sidedef->toptexture)
&& ((backf1 <= frontf1 && backf2 >= frontf2) || seg->sidedef->bottomtexture)
&& (abacksector->ceilingpic != skyflatnum || afrontsector->ceilingpic != skyflatnum));
if (mydoorclosed)
{
checkforemptylines = false;
return true;
}
}
// Window.
// We know it's a window when the above isn't true and the back and front sectors don't match
if (backc1 != frontc1 || backc2 != frontc2
|| backf1 != frontf1 || backf2 != frontf2)
{
checkforemptylines = false;
return false;
}
// In this case we just need to check whether there is actually a need to render any lines, so checkforempty lines
// stays true
return false; return false;
} }
#else #else
@ -5497,7 +5544,7 @@ static void HWR_AddSprites(sector_t *sec)
} }
#ifdef HWPRECIP #ifdef HWPRECIP
// Someone seriously wants infinite draw distance for precipitation? // No to infinite precipitation draw distance.
if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS)) if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS))
{ {
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
@ -5513,13 +5560,6 @@ static void HWR_AddSprites(sector_t *sec)
HWR_ProjectPrecipitationSprite(precipthing); HWR_ProjectPrecipitationSprite(precipthing);
} }
} }
else
{
// Draw everything in sector, no checks
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
if (!(precipthing->precipflags & PCF_INVISIBLE))
HWR_ProjectPrecipitationSprite(precipthing);
}
#endif #endif
} }
@ -5882,13 +5922,15 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
static void HWR_DrawSkyBackground(void) static void HWR_DrawSkyBackground(void)
{ {
FOutVector v[4]; FOutVector v[4];
texture_t *tex;
angle_t angle; angle_t angle;
float dimensionmultiply; float dimensionmultiply;
float aspectratio; float aspectratio;
float angleturn; float angleturn;
tex = textures[texturetranslation[skytexture]];
HWR_GetTexture(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 //Hurdler: the sky is the only texture who need 4.0f instead of 1.0
// because it's called just after clearing the screen // because it's called just after clearing the screen
@ -5912,22 +5954,22 @@ static void HWR_DrawSkyBackground(void)
// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly // 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 // 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]); angle = -(dup_viewangle + gr_xtoviewangle[0]);
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); dimensionmultiply = ((float)tex->width/256.0f);
if (atransform.mirror) if (atransform.mirror)
{ {
angle = InvAngle(angle); angle = InvAngle(angle);
dimensionmultiply *= -1; dimensionmultiply = -dimensionmultiply;
} }
v[0].sow = v[3].sow = ((float) angle / ((ANGLE_90-1)*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 // Y
angle = aimingangle; angle = aimingangle;
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio)); dimensionmultiply = ((float)tex->height/(128.0f*aspectratio));
if (splitscreen == 1) if (splitscreen == 1)
{ {

View file

@ -653,13 +653,12 @@ spritemd2found:
// 0.2126 to red // 0.2126 to red
// 0.7152 to green // 0.7152 to green
// 0.0722 to blue // 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) \ #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) 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; UINT16 w = gpatch->width, h = gpatch->height;
UINT32 size = w*h; UINT32 size = w*h;
RGBA_t *image, *blendimage, *cur, blendcolor; 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; image = gpatch->mipmap.grInfo.data;
blendimage = blendgpatch->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; UINT16 brightness;
const UINT8 start = 4;
UINT32 r, g, b;
blendcolor = V_GetColor(colortranslations[color][start]); // Don't bother with blending the pixel if the alpha of the blend pixel is 0
r = (UINT32)(blendcolor.s.red*blendcolor.s.red); if (skinnum == TC_RAINBOW)
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--)
{ {
if (image->s.alpha == 0 && blendimage->s.alpha == 0) 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->rgba = image->rgba;
cur++; image++; blendimage++;
continue;
} }
else else
{ {
UINT32 tempcolor; UINT16 imagebright, blendbright;
UINT16 imagebright, blendbright, finalbright, colorbright;
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue);
SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->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 // 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; brightness = (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;
} }
cur++; image++; blendimage++;
} }
} else
else
{
while (size--)
{ {
if (blendimage->s.alpha == 0) 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->rgba = image->rgba;
cur++; image++; blendimage++;
continue;
} }
else else
{ {
INT32 tempcolor; SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
INT16 tempmult, tempalpha; }
tempalpha = -(abs(blendimage->s.red-127)-127)*2; }
if (tempalpha > 255)
tempalpha = 255;
else if (tempalpha < 0)
tempalpha = 0;
tempmult = (blendimage->s.red-127)*2; // Calculate a sort of "gradient" for the skincolor
if (tempmult > 255) // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...)
tempmult = 255; {
else if (tempmult < 0) RGBA_t nextcolor;
tempmult = 0; 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; // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors.
cur->s.red = (UINT8)tempcolor; // Ensue horrible mess.
tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255; if (skinnum == TC_RAINBOW)
cur->s.green = (UINT8)tempcolor; {
tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255; UINT16 brightdif = 256;
cur->s.blue = (UINT8)tempcolor; UINT8 colorbrightnesses[16];
cur->s.alpha = image->s.alpha; 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; return;
@ -1091,11 +1176,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
#ifdef USE_FTRANSFORM_ANGLEZ #ifdef USE_FTRANSFORM_ANGLEZ
// Slope rotation from Kart // Slope rotation from Kart
p.anglez = 0.0f; p.anglez = 0.0f;
if (spr->mobj->standingslope) if (spr->mobj->modeltilt)
{ {
fixed_t tempz = spr->mobj->standingslope->normal.z; fixed_t tempz = spr->mobj->modeltilt->normal.z;
fixed_t tempy = spr->mobj->standingslope->normal.y; fixed_t tempy = spr->mobj->modeltilt->normal.y;
fixed_t tempx = spr->mobj->standingslope->normal.x; fixed_t tempx = spr->mobj->modeltilt->normal.x;
fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
p.anglez = FIXED_TO_FLOAT(tempangle); p.anglez = FIXED_TO_FLOAT(tempangle);
tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy));

View file

@ -2386,7 +2386,7 @@ void HU_Drawer(void)
}*/ }*/
// draw song credits // draw song credits
if (cv_songcredits.value) if (cv_songcredits.value && !( hu_showscores && (netgame || multiplayer) ))
HU_DrawSongCredits(); HU_DrawSongCredits();
// draw desynch text // draw desynch text

View file

@ -1311,7 +1311,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
int gaie; int gaie;
if (!port || !port[0]) if (!port || !port[0])
port = port_name; port = DEFAULTPORT;
DEBFILE(va("Creating new node: %s@%s\n", address, port)); DEBFILE(va("Creating new node: %s@%s\n", address, port));

View file

@ -43,33 +43,34 @@ char sprnames[NUMSPRITES + 1][5] =
"DFLM","XMS1","XMS2","XMS3","BSZ1","BSZ2","BSZ3","BSZ4","BSZ5","BSZ6", "DFLM","XMS1","XMS2","XMS3","BSZ1","BSZ2","BSZ3","BSZ4","BSZ5","BSZ6",
"BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN", "BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN",
"ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC", "ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC",
"COWZ","RBRD","SPRY","SPRR","SPRB","YSPR","RSPR","RAIN","SNO1","SPLH", "COWZ","RBRD","SPVY","SPVR","SPVB","SPVG","SPDY","SPDR","SPDB","SPDG",
"SPLA","SMOK","BUBP","BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL", "SPHY","SPHR","SPHB","SPHG","RAIN","SNO1","SPLH","SPLA","SMOK","BUBP",
"SCOR","DRWN","TTAG","GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE", "BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL","SCOR","DRWN","TTAG",
"RNGS","RNGG","PIKB","PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE", "GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE","RNGS","RNGG","PIKB",
"TSCR","COIN","CPRK","GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM", "PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE","TSCR","COIN","CPRK",
"KOOP","BFLM","MAXE","MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL", "GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM","KOOP","BFLM","MAXE",
"NSPK","NBMP","HOOP","NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2", "MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL","NSPK","NBMP","HOOP",
"BOM3","BOM4","ROIA","ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH", "NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2","BOM3","BOM4","ROIA",
"ROII","ROIJ","ROIK","ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG", "ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH","ROII","ROIJ","ROIK",
"GWLR","SRBA","SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI", "ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG","GWLR","SRBA","SRBB",
"SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", "SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL",
"SRBM","SRBN","SRBO",
//SRB2kart Sprites //SRB2kart Sprites
"SPRG","BSPR","RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE", "RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE","KINV","KINF",
"KINV","KINF","WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN", "WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN","JAWZ","SSMN",
"JAWZ","SSMN","KRBM","BHOG","BHBM","SPBM","THNS","SINK","SITR","KBLN", "KRBM","BHOG","BHBM","SPBM","THNS","SINK","SITR","KBLN","DEZL","POKE",
"DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM", "AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM","SACO","CRAB",
"SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB", "SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB","ARRO","ITEM",
"ARRO","ITEM","ITMO","ITMI","ITMN","WANT","PBOM","HIT1","HIT2","HIT3", "ITMO","ITMI","ITMN","WANT","PBOM","HIT1","HIT2","HIT3","RETI","AIDU",
"RETI","AIDU","KSPK","LZI1","LZI2","KLIT","FZSM","FZBM","FPRT","SBUS", "KSPK","LZI1","LZI2","KLIT","FZSM","FZBM","FPRT","SBUS","MARB","FUFO",
"MARB","FUFO","RUST","BLON","VAPE","HTZA","HTZB","SGVA","SGVB","SGVC", "RUST","BLON","VAPE","HTZA","HTZB","SGVA","SGVB","SGVC","PGTR","PGF1",
"PGTR","PGF1","PGF2","PGF3","PGBH","DPLR","SPTL","ENM1","GARU","MARR", "PGF2","PGF3","PGBH","DPLR","SPTL","ENM1","GARU","MARR","REAP","JITB",
"REAP","JITB","CDMO","CDBU","PINE","PPLR","DPPT","AATR","COCO","BDST", "CDMO","CDBU","PINE","PPLR","DPPT","AATR","COCO","BDST","FROG","CBRA",
"FROG","CBRA","HOLE","BBRA","EGFG","SMKP","MTYM","THWP","SNOB","ICEB", "HOLE","BBRA","EGFG","SMKP","MTYM","THWP","SNOB","ICEB","CNDL","DOCH",
"CNDL","DOCH","DUCK","GTRE","CHES","CHIM","DRGN","LZMN","PGSS","ZTCH", "DUCK","GTRE","CHES","CHIM","DRGN","LZMN","PGSS","ZTCH","MKMA","MKMP",
"MKMA","MKMP","RTCH","BOWL","BOWH","BRRL","BRRR","HRSE","TOAH","BFRT", "RTCH","BOWL","BOWH","BRRL","BRRR","HRSE","TOAH","BFRT","OFRT","RFRT",
"OFRT","RFRT","PFRT","ASPK","HBST","HBSO","HBSF","WBLZ","WBLN","FWRK", "PFRT","ASPK","HBST","HBSO","HBSF","WBLZ","WBLN","FWRK","MXCL","RGSP",
"MXCL","RGSP","DRAF","XMS4","XMS5","VIEW" "DRAF","GRES","XMS4","XMS5","VIEW"
}; };
// Doesn't work with g++, needs actionf_p1 (don't modify this comment) // Doesn't work with g++, needs actionf_p1 (don't modify this comment)
@ -1795,45 +1796,76 @@ state_t states[NUMSTATES] =
{SPR_RBRD, 1, 4, {A_Chase}, 0, 0, S_RBIRD2}, // S_RBIRD3 {SPR_RBRD, 1, 4, {A_Chase}, 0, 0, S_RBIRD2}, // S_RBIRD3
// Yellow Spring // Yellow Spring
{SPR_SPRY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWSPRING {SPR_SPVY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWSPRING1
{SPR_SPRY, 4, 4, {A_Pain}, 0, 0, S_YELLOWSPRING3}, // S_YELLOWSPRING2 {SPR_SPVY, 1, 1, {A_Pain}, 0, 0, S_YELLOWSPRING3}, // S_YELLOWSPRING2
{SPR_SPRY, 3, 1, {NULL}, 0, 0, S_YELLOWSPRING4}, // S_YELLOWSPRING3 {SPR_SPVY, 0, 1, {NULL}, 0, 0, S_YELLOWSPRING4}, // S_YELLOWSPRING3
{SPR_SPRY, 2, 1, {NULL}, 0, 0, S_YELLOWSPRING5}, // S_YELLOWSPRING4 {SPR_SPVY, 2, 4, {NULL}, 0, 0, S_YELLOWSPRING1}, // S_YELLOWSPRING4
{SPR_SPRY, 1, 1, {NULL}, 0, 0, S_YELLOWSPRING}, // S_YELLOWSPRING5
// Red Spring // Red Spring
{SPR_SPRR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDSPRING {SPR_SPVR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDSPRING1
{SPR_SPRR, 4, 4, {A_Pain}, 0, 0, S_REDSPRING3}, // S_REDSPRING2 {SPR_SPVR, 1, 1, {A_Pain}, 0, 0, S_REDSPRING3}, // S_REDSPRING2
{SPR_SPRR, 3, 1, {NULL}, 0, 0, S_REDSPRING4}, // S_REDSPRING3 {SPR_SPVR, 0, 1, {NULL}, 0, 0, S_REDSPRING4}, // S_REDSPRING3
{SPR_SPRR, 2, 1, {NULL}, 0, 0, S_REDSPRING5}, // S_REDSPRING4 {SPR_SPVR, 2, 4, {NULL}, 0, 0, S_REDSPRING1}, // S_REDSPRING4
{SPR_SPRR, 1, 1, {NULL}, 0, 0, S_REDSPRING}, // S_REDSPRING5
// Blue Spring // Blue Spring
{SPR_SPRB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPRING {SPR_SPVB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPRING1
{SPR_SPRB, 4, 4, {A_Pain}, 0, 0, S_BLUESPRING3}, // S_BLUESPRING2 {SPR_SPVB, 1, 1, {A_Pain}, 0, 0, S_BLUESPRING3}, // S_BLUESPRING2
{SPR_SPRB, 3, 1, {NULL}, 0, 0, S_BLUESPRING4}, // S_BLUESPRING3 {SPR_SPVB, 0, 1, {NULL}, 0, 0, S_BLUESPRING4}, // S_BLUESPRING3
{SPR_SPRB, 2, 1, {NULL}, 0, 0, S_BLUESPRING5}, // S_BLUESPRING4 {SPR_SPVB, 2, 4, {NULL}, 0, 0, S_BLUESPRING1}, // S_BLUESPRING4
{SPR_SPRB, 1, 1, {NULL}, 0, 0, S_BLUESPRING}, // S_BLUESPRING5
// Grey Spring
{SPR_SPVG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GREYSPRING1
{SPR_SPVG, 1, 1, {A_Pain}, 0, 0, S_GREYSPRING3}, // S_GREYSPRING2
{SPR_SPVG, 0, 1, {NULL}, 0, 0, S_GREYSPRING4}, // S_GREYSPRING3
{SPR_SPVG, 2, 4, {NULL}, 0, 0, S_GREYSPRING1}, // S_GREYSPRING4
// Yellow Diagonal Spring // Yellow Diagonal Spring
{SPR_YSPR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YDIAG1 {SPR_SPDY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YDIAG1
{SPR_YSPR, 1, 1, {A_Pain}, 0, 0, S_YDIAG3}, // S_YDIAG2 {SPR_SPDY, 1, 1, {A_Pain}, 0, 0, S_YDIAG3}, // S_YDIAG2
{SPR_YSPR, 2, 1, {NULL}, 0, 0, S_YDIAG4}, // S_YDIAG3 {SPR_SPDY, 0, 1, {NULL}, 0, 0, S_YDIAG4}, // S_YDIAG3
{SPR_YSPR, 3, 1, {NULL}, 0, 0, S_YDIAG5}, // S_YDIAG4 {SPR_SPDY, 2, 4, {NULL}, 0, 0, S_YDIAG1}, // S_YDIAG4
{SPR_YSPR, 4, 1, {NULL}, 0, 0, S_YDIAG6}, // S_YDIAG5
{SPR_YSPR, 3, 1, {NULL}, 0, 0, S_YDIAG7}, // S_YDIAG6
{SPR_YSPR, 2, 1, {NULL}, 0, 0, S_YDIAG8}, // S_YDIAG7
{SPR_YSPR, 1, 1, {NULL}, 0, 0, S_YDIAG1}, // S_YDIAG8
// Red Diagonal Spring // Red Diagonal Spring
{SPR_RSPR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RDIAG1 {SPR_SPDR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RDIAG1
{SPR_RSPR, 1, 1, {A_Pain}, 0, 0, S_RDIAG3}, // S_RDIAG2 {SPR_SPDR, 1, 1, {A_Pain}, 0, 0, S_RDIAG3}, // S_RDIAG2
{SPR_RSPR, 2, 1, {NULL}, 0, 0, S_RDIAG4}, // S_RDIAG3 {SPR_SPDR, 0, 1, {NULL}, 0, 0, S_RDIAG4}, // S_RDIAG3
{SPR_RSPR, 3, 1, {NULL}, 0, 0, S_RDIAG5}, // S_RDIAG4 {SPR_SPDR, 2, 4, {NULL}, 0, 0, S_RDIAG1}, // S_RDIAG4
{SPR_RSPR, 4, 1, {NULL}, 0, 0, S_RDIAG6}, // S_RDIAG5
{SPR_RSPR, 3, 1, {NULL}, 0, 0, S_RDIAG7}, // S_RDIAG6 // Blue Diagonal Spring
{SPR_RSPR, 2, 1, {NULL}, 0, 0, S_RDIAG8}, // S_RDIAG7 {SPR_SPDB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BDIAG1
{SPR_RSPR, 1, 1, {NULL}, 0, 0, S_RDIAG1}, // S_RDIAG8 {SPR_SPDB, 1, 1, {A_Pain}, 0, 0, S_BDIAG3}, // S_BDIAG2
{SPR_SPDB, 0, 1, {NULL}, 0, 0, S_BDIAG4}, // S_BDIAG3
{SPR_SPDB, 2, 4, {NULL}, 0, 0, S_BDIAG1}, // S_BDIAG4
// Grey Diagonal Spring
{SPR_SPDG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GDIAG1
{SPR_SPDG, 1, 1, {A_Pain}, 0, 0, S_GDIAG3}, // S_GDIAG2
{SPR_SPDG, 0, 1, {NULL}, 0, 0, S_GDIAG4}, // S_GDIAG3
{SPR_SPDG, 2, 4, {NULL}, 0, 0, S_GDIAG1}, // S_GDIAG4
// Yellow Horizontal Spring
{SPR_SPHY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YHORIZ1
{SPR_SPHY, 1, 1, {A_Pain}, 0, 0, S_YHORIZ3}, // S_YHORIZ2
{SPR_SPHY, 0, 1, {NULL}, 0, 0, S_YHORIZ4}, // S_YHORIZ3
{SPR_SPHY, 2, 4, {NULL}, 0, 0, S_YHORIZ1}, // S_YHORIZ4
// Red Horizontal Spring
{SPR_SPHR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RHORIZ1
{SPR_SPHR, 1, 1, {A_Pain}, 0, 0, S_RHORIZ3}, // S_RHORIZ2
{SPR_SPHR, 0, 1, {NULL}, 0, 0, S_RHORIZ4}, // S_RHORIZ3
{SPR_SPHR, 2, 4, {NULL}, 0, 0, S_RHORIZ1}, // S_RHORIZ4
// Blue Horizontal Spring
{SPR_SPHB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BHORIZ1
{SPR_SPHB, 1, 1, {A_Pain}, 0, 0, S_BHORIZ3}, // S_BHORIZ2
{SPR_SPHB, 0, 1, {NULL}, 0, 0, S_BHORIZ4}, // S_BHORIZ3
{SPR_SPHB, 2, 4, {NULL}, 0, 0, S_BHORIZ1}, // S_BHORIZ4
// Grey Horizontal Spring
{SPR_SPHG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GHORIZ1
{SPR_SPHG, 1, 1, {A_Pain}, 0, 0, S_GHORIZ3}, // S_GHORIZ2
{SPR_SPHG, 0, 1, {NULL}, 0, 0, S_GHORIZ4}, // S_GHORIZ3
{SPR_SPHG, 2, 4, {NULL}, 0, 0, S_GHORIZ1}, // S_GHORIZ4
// Rain // Rain
{SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1 {SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1
@ -2512,23 +2544,6 @@ state_t states[NUMSTATES] =
{SPR_SRBO, 0, 2, {A_BuzzFly}, 0, 0, S_SRB1_GENREX2}, // S_SRB1_GENREX2 {SPR_SRBO, 0, 2, {A_BuzzFly}, 0, 0, S_SRB1_GENREX2}, // S_SRB1_GENREX2
// SRB2kart // SRB2kart
{SPR_SPRG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GRAYSPRING
{SPR_SPRG, 4, 4, {A_Pain}, 0, 0, S_GRAYSPRING3}, // S_GRAYSPRING2
{SPR_SPRG, 3, 1, {NULL}, 0, 0, S_GRAYSPRING4}, // S_GRAYSPRING3
{SPR_SPRG, 2, 1, {NULL}, 0, 0, S_GRAYSPRING5}, // S_GRAYSPRING4
{SPR_SPRG, 1, 1, {NULL}, 0, 0, S_GRAYSPRING}, // S_GRAYSPRING5
{SPR_NULL, 0, 1, {A_Pain}, 0, 0, S_INVISIBLE}, // S_INVISSPRING
{SPR_BSPR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BDIAG1
{SPR_BSPR, 1, 1, {A_Pain}, 0, 0, S_BDIAG3}, // S_BDIAG2
{SPR_BSPR, 2, 1, {NULL}, 0, 0, S_BDIAG4}, // S_BDIAG3
{SPR_BSPR, 3, 1, {NULL}, 0, 0, S_BDIAG5}, // S_BDIAG4
{SPR_BSPR, 4, 1, {NULL}, 0, 0, S_BDIAG6}, // S_BDIAG5
{SPR_BSPR, 3, 1, {NULL}, 0, 0, S_BDIAG7}, // S_BDIAG6
{SPR_BSPR, 2, 1, {NULL}, 0, 0, S_BDIAG8}, // S_BDIAG7
{SPR_BSPR, 1, 1, {NULL}, 0, 0, S_BDIAG1}, // S_BDIAG8
{SPR_RNDM, 0|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM2}, // S_RANDOMITEM1 {SPR_RNDM, 0|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM2}, // S_RANDOMITEM1
{SPR_RNDM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM3}, // S_RANDOMITEM2 {SPR_RNDM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM3}, // S_RANDOMITEM2
{SPR_RNDM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM4}, // S_RANDOMITEM3 {SPR_RNDM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM4}, // S_RANDOMITEM3
@ -3437,6 +3452,8 @@ state_t states[NUMSTATES] =
{SPR_DRAF, 3, 1, {NULL}, 0, 0, S_DRAFTDUST5}, // S_DRAFTDUST4 {SPR_DRAF, 3, 1, {NULL}, 0, 0, S_DRAFTDUST5}, // S_DRAFTDUST4
{SPR_DRAF, 4, 1, {NULL}, 0, 0, S_NULL}, // S_DRAFTDUST5 {SPR_DRAF, 4, 1, {NULL}, 0, 0, S_NULL}, // S_DRAFTDUST5
{SPR_GRES, FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 2, 4, S_NULL}, // S_TIREGREASE
#ifdef SEENAMES #ifdef SEENAMES
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
#endif #endif
@ -4236,8 +4253,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
32, // reactiontime 32, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
S_NULL, // painstate S_NULL, // painstate
0, // painchance SKINCOLOR_TEA, // painchance
sfx_spring, // painsound sfx_s3kb1, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_XPLD1, // deathstate S_XPLD1, // deathstate
@ -4247,7 +4264,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
24*FRACUNIT, // radius 24*FRACUNIT, // radius
40*FRACUNIT, // height 40*FRACUNIT, // height
0, // display offset 0, // display offset
13*FRACUNIT, // mass 15*FRACUNIT, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags
@ -4263,8 +4280,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
32, // reactiontime 32, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
S_NULL, // painstate S_NULL, // painstate
0, // painchance SKINCOLOR_YELLOW, // painchance
sfx_spring, // painsound sfx_s3kb1, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_XPLD1, // deathstate S_XPLD1, // deathstate
@ -4274,7 +4291,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
24*FRACUNIT, // radius 24*FRACUNIT, // radius
40*FRACUNIT, // height 40*FRACUNIT, // height
0, // display offset 0, // display offset
26*FRACUNIT, // mass 25*FRACUNIT, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags
@ -4681,7 +4698,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // display offset 0, // display offset
0, // mass 0, // mass
0, // damage 0, // damage
sfx_spring, // activesound sfx_s3kb1, // activesound
MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags
S_EGGMOBILE2_POGO5 // raisestate S_EGGMOBILE2_POGO5 // raisestate
}, },
@ -6058,54 +6075,27 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_BLUESPRING
552, // doomednum
S_BLUESPRING, // spawnstate
1000, // spawnhealth
S_BLUESPRING2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_spring, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
20*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
14*FRACUNIT, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
S_BLUESPRING2 // raisestate
},
{ // MT_YELLOWSPRING { // MT_YELLOWSPRING
550, // doomednum 550, // doomednum
S_YELLOWSPRING, // spawnstate S_YELLOWSPRING1,// spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_YELLOWSPRING2,// seestate S_YELLOWSPRING2,// seestate
sfx_None, // seesound sfx_None, // seesound
8, // reactiontime 8, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
S_NULL, // painstate S_NULL, // painstate
0, // painchance SKINCOLOR_YELLOW, // painchance
sfx_spring, // painsound sfx_s3kb1, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_NULL, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
0, // speed 0, // speed
20*FRACUNIT, // radius 48*FRACUNIT, // radius
16*FRACUNIT, // height 32*FRACUNIT, // height
0, // display offset 0, // display offset
26*FRACUNIT, // mass 25*FRACUNIT, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
@ -6114,23 +6104,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_REDSPRING { // MT_REDSPRING
551, // doomednum 551, // doomednum
S_REDSPRING, // spawnstate S_REDSPRING1, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_REDSPRING2, // seestate S_REDSPRING2, // seestate
sfx_None, // seesound sfx_None, // seesound
8, // reactiontime 8, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
S_NULL, // painstate S_NULL, // painstate
0, // painchance SKINCOLOR_SALMON, // painchance
sfx_spring, // painsound sfx_s3kb1, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_NULL, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
0, // speed 0, // speed
20*FRACUNIT, // radius 48*FRACUNIT, // radius
16*FRACUNIT, // height 32*FRACUNIT, // height
0, // display offset 0, // display offset
40*FRACUNIT, // mass 40*FRACUNIT, // mass
0, // damage 0, // damage
@ -6139,8 +6129,62 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_REDSPRING2 // raisestate S_REDSPRING2 // raisestate
}, },
{ // MT_BLUESPRING
552, // doomednum
S_BLUESPRING1, // spawnstate
1000, // spawnhealth
S_BLUESPRING2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
SKINCOLOR_PASTEL, // painchance
sfx_s3kb1, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
64*FRACUNIT, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
S_BLUESPRING2 // raisestate
},
{ // MT_GREYSPRING
553, // doomednum
S_GREYSPRING1, // spawnstate
1000, // spawnhealth
S_GREYSPRING2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
SKINCOLOR_POPCORN, // painchance
sfx_s3kb1, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
15*FRACUNIT, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
S_GREYSPRING2 // raisestate
},
{ // MT_YELLOWDIAG { // MT_YELLOWDIAG
555, // doomednum 554, // doomednum
S_YDIAG1, // spawnstate S_YDIAG1, // spawnstate
1, // spawnhealth 1, // spawnhealth
S_YDIAG2, // seestate S_YDIAG2, // seestate
@ -6148,26 +6192,26 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
8, // reactiontime 8, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
S_NULL, // painstate S_NULL, // painstate
0, // painchance SKINCOLOR_YELLOW, // painchance
sfx_spring, // painsound sfx_s3kb1, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_NULL, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
0, // speed 0, // speed
16*FRACUNIT, // radius 48*FRACUNIT, // radius
16*FRACUNIT, // height 56*FRACUNIT, // height
0, // display offset 0, // display offset
26*FRACUNIT, // mass 25*FRACUNIT, // mass
26*FRACUNIT, // damage 25*FRACUNIT, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
S_YDIAG2 // raisestate S_YDIAG2 // raisestate
}, },
{ // MT_REDDIAG { // MT_REDDIAG
556, // doomednum 555, // doomednum
S_RDIAG1, // spawnstate S_RDIAG1, // spawnstate
1, // spawnhealth 1, // spawnhealth
S_RDIAG2, // seestate S_RDIAG2, // seestate
@ -6175,16 +6219,16 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
8, // reactiontime 8, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
S_NULL, // painstate S_NULL, // painstate
0, // painchance SKINCOLOR_SALMON, // painchance
sfx_spring, // painsound sfx_s3kb1, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_NULL, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
0, // speed 0, // speed
16*FRACUNIT, // radius 48*FRACUNIT, // radius
16*FRACUNIT, // height 56*FRACUNIT, // height
0, // display offset 0, // display offset
40*FRACUNIT, // mass 40*FRACUNIT, // mass
40*FRACUNIT, // damage 40*FRACUNIT, // damage
@ -6193,6 +6237,168 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_RDIAG2 // raisestate S_RDIAG2 // raisestate
}, },
{ // MT_BLUEDIAG
556, // doomednum
S_BDIAG1, // spawnstate
1, // spawnhealth
S_BDIAG2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
SKINCOLOR_PASTEL, // painchance
sfx_s3kb1, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
56*FRACUNIT, // height
0, // display offset
64*FRACUNIT, // mass
64*FRACUNIT, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
S_BDIAG2 // raisestate
},
{ // MT_GREYDIAG
557, // doomednum
S_GDIAG1, // spawnstate
1, // spawnhealth
S_GDIAG2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
SKINCOLOR_POPCORN, // painchance
sfx_s3kb1, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
56*FRACUNIT, // height
0, // display offset
15*FRACUNIT, // mass
15*FRACUNIT, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
S_GDIAG2 // raisestate
},
{ // MT_YELLOWHORIZ
558, // doomednum
S_YHORIZ1, // spawnstate
1, // spawnhealth
S_YHORIZ2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
SKINCOLOR_YELLOW, // painchance
sfx_s3kb1, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
56*FRACUNIT, // height
0, // display offset
0, // mass
45*FRACUNIT, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
S_YHORIZ2 // raisestate
},
{ // MT_REDHORIZ
559, // doomednum
S_RHORIZ1, // spawnstate
1, // spawnhealth
S_RHORIZ2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
SKINCOLOR_SALMON, // painchance
sfx_s3kb1, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
56*FRACUNIT, // height
0, // display offset
0, // mass
72*FRACUNIT, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
S_RHORIZ2 // raisestate
},
{ // MT_BLUEHORIZ
560, // doomednum
S_BHORIZ1, // spawnstate
1, // spawnhealth
S_BHORIZ2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
SKINCOLOR_PASTEL, // painchance
sfx_s3kb1, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
56*FRACUNIT, // height
0, // display offset
0, // mass
115*FRACUNIT, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
S_BHORIZ2 // raisestate
},
{ // MT_GREYHORIZ
561, // doomednum
S_GHORIZ1, // spawnstate
1, // spawnhealth
S_GHORIZ2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
SKINCOLOR_POPCORN, // painchance
sfx_s3kb1, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
56*FRACUNIT, // height
0, // display offset
0, // mass
27*FRACUNIT, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
S_GHORIZ2 // raisestate
},
{ // MT_BUBBLES { // MT_BUBBLES
500, // doomednum 500, // doomednum
S_BUBBLES1, // spawnstate S_BUBBLES1, // spawnstate
@ -14800,88 +15006,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
}, },
// SRB2kart MT's // SRB2kart MT's
{ // MT_GRAYSPRING
553, // doomednum
S_GRAYSPRING, // spawnstate
100, // spawnhealth
S_GRAYSPRING2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_spring, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
20*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
6*FRACUNIT, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
S_GRAYSPRING2 // raisestate
},
{ // MT_INVISSPRING
554, // doomednum
S_INVISIBLE, // spawnstate
100, // spawnhealth
S_INVISSPRING, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_spring, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
20*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
6*FRACUNIT, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING, // flags
S_INVISSPRING // raisestate
},
{ // MT_BLUEDIAG
557, // doomednum
S_BDIAG1, // spawnstate
1, // spawnhealth
S_BDIAG2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_spring, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
14*FRACUNIT, // mass
14*FRACUNIT, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
S_BDIAG2 // raisestate
},
{ // MT_RANDOMITEM { // MT_RANDOMITEM
2000, // doomednum 2000, // doomednum
S_RANDOMITEM1, // spawnstate S_RANDOMITEM1, // spawnstate
@ -20149,6 +20273,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_TIREGREASE
-1, // doomednum
S_TIREGREASE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8<<FRACBITS, // radius
16<<FRACBITS, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
// ============================================================================================================================// // ============================================================================================================================//
#ifdef SEENAMES #ifdef SEENAMES

View file

@ -459,11 +459,18 @@ typedef enum sprite
SPR_RBRD, // Red Birdie in Bubble SPR_RBRD, // Red Birdie in Bubble
// Springs // Springs
SPR_SPRY, // yellow spring SPR_SPVY, // Yellow Vertical Spring
SPR_SPRR, // red spring SPR_SPVR, // Red Vertical Spring
SPR_SPRB, // Blue springs SPR_SPVB, // Blue Vertical Spring
SPR_YSPR, // Yellow Diagonal Spring SPR_SPVG, // Grey Vertical Spring
SPR_RSPR, // Red Diagonal 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 // Environmental Effects
SPR_RAIN, // Rain SPR_RAIN, // Rain
@ -587,9 +594,6 @@ typedef enum sprite
SPR_SRBO, SPR_SRBO,
// Springs // Springs
SPR_SPRG, // Gray Spring
SPR_BSPR, // Blue Diagonal Spring
SPR_RNDM, // Random Item Box SPR_RNDM, // Random Item Box
SPR_RPOP, // Random Item Box Pop SPR_RPOP, // Random Item Box Pop
SPR_SGNS, // Signpost sparkle SPR_SGNS, // Signpost sparkle
@ -778,6 +782,7 @@ typedef enum sprite
SPR_MXCL, SPR_MXCL,
SPR_RGSP, SPR_RGSP,
SPR_DRAF, SPR_DRAF,
SPR_GRES,
// Xmas-specific sprites that don't fit aboxe // Xmas-specific sprites that don't fit aboxe
SPR_XMS4, SPR_XMS4,
@ -2491,44 +2496,77 @@ typedef enum state
S_RBIRD2, S_RBIRD2,
S_RBIRD3, S_RBIRD3,
S_YELLOWSPRING, // Yellow Spring
S_YELLOWSPRING1,
S_YELLOWSPRING2, S_YELLOWSPRING2,
S_YELLOWSPRING3, S_YELLOWSPRING3,
S_YELLOWSPRING4, S_YELLOWSPRING4,
S_YELLOWSPRING5,
S_REDSPRING, // Red Spring
S_REDSPRING1,
S_REDSPRING2, S_REDSPRING2,
S_REDSPRING3, S_REDSPRING3,
S_REDSPRING4, S_REDSPRING4,
S_REDSPRING5,
// Blue Springs // Blue Spring
S_BLUESPRING, S_BLUESPRING1,
S_BLUESPRING2, S_BLUESPRING2,
S_BLUESPRING3, S_BLUESPRING3,
S_BLUESPRING4, S_BLUESPRING4,
S_BLUESPRING5,
// Grey Spring
S_GREYSPRING1,
S_GREYSPRING2,
S_GREYSPRING3,
S_GREYSPRING4,
// Yellow Diagonal Spring // Yellow Diagonal Spring
S_YDIAG1, S_YDIAG1,
S_YDIAG2, S_YDIAG2,
S_YDIAG3, S_YDIAG3,
S_YDIAG4, S_YDIAG4,
S_YDIAG5,
S_YDIAG6,
S_YDIAG7,
S_YDIAG8,
// Red Diagonal Spring // Red Diagonal Spring
S_RDIAG1, S_RDIAG1,
S_RDIAG2, S_RDIAG2,
S_RDIAG3, S_RDIAG3,
S_RDIAG4, S_RDIAG4,
S_RDIAG5,
S_RDIAG6, // Blue Diagonal Spring
S_RDIAG7, S_BDIAG1,
S_RDIAG8, 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 // Rain
S_RAIN1, S_RAIN1,
@ -3153,26 +3191,6 @@ typedef enum state
S_SRB1_GENREX1, S_SRB1_GENREX1,
S_SRB1_GENREX2, 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 //{ Random Item Box
S_RANDOMITEM1, S_RANDOMITEM1,
S_RANDOMITEM2, S_RANDOMITEM2,
@ -4096,6 +4114,8 @@ typedef enum state
S_DRAFTDUST4, S_DRAFTDUST4,
S_DRAFTDUST5, S_DRAFTDUST5,
S_TIREGREASE,
#ifdef SEENAMES #ifdef SEENAMES
S_NAMECHECK, S_NAMECHECK,
#endif #endif
@ -4242,11 +4262,18 @@ typedef enum mobj_type
// Springs and others // Springs and others
MT_FAN, MT_FAN,
MT_STEAM, // Steam riser MT_STEAM, // Steam riser
MT_BLUESPRING,
MT_YELLOWSPRING, MT_YELLOWSPRING,
MT_REDSPRING, MT_REDSPRING,
MT_BLUESPRING,
MT_GREYSPRING,
MT_YELLOWDIAG, // Yellow Diagonal Spring MT_YELLOWDIAG, // Yellow Diagonal Spring
MT_REDDIAG, // Red 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 // Interactive Objects
MT_BUBBLES, // Bubble source MT_BUBBLES, // Bubble source
@ -4628,9 +4655,6 @@ typedef enum mobj_type
MT_SRB1_GENREX, MT_SRB1_GENREX,
// SRB2kart // SRB2kart
MT_GRAYSPRING,
MT_INVISSPRING,
MT_BLUEDIAG,
MT_RANDOMITEM, MT_RANDOMITEM,
MT_RANDOMITEMPOP, MT_RANDOMITEMPOP,
MT_FLOATINGITEM, MT_FLOATINGITEM,
@ -4901,6 +4925,7 @@ typedef enum mobj_type
MT_KARMAFIREWORK, MT_KARMAFIREWORK,
MT_RINGSPARKS, MT_RINGSPARKS,
MT_DRAFTDUST, MT_DRAFTDUST,
MT_TIREGREASE,
#ifdef SEENAMES #ifdef SEENAMES
MT_NAMECHECK, MT_NAMECHECK,

View file

@ -410,7 +410,7 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
// 0.0722 to blue // 0.0722 to blue
// (See this same define in hw_md2.c!) // (See this same define in hw_md2.c!)
#define SETBRIGHTNESS(brightness,r,g,b) \ #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 /** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power
@ -1623,7 +1623,7 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur
cury + (P_RandomRange(-12,12)*mapobjectscale), cury + (P_RandomRange(-12,12)*mapobjectscale),
curz + (P_RandomRange(24,48)*mapobjectscale), curz + (P_RandomRange(24,48)*mapobjectscale),
MT_SIGNSPARKLE); 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)); P_SetScale(band, (band->destscale = (3*player->mo->scale)/2));
band->color = colors[c]; band->color = colors[c];
band->colorized = true; band->colorized = true;
@ -1637,7 +1637,7 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur
curx += stepx; curx += stepx;
cury += stepy; cury += stepy;
curz += stepz; curz += stepz;
offset = abs(offset-1) % 3; offset = abs(offset-1) % 3;
n--; n--;
} }
@ -2320,6 +2320,9 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove
// ACCELCODE!!!1!11! // ACCELCODE!!!1!11!
oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale); 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); 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 if (player->kartstuff[k_pogospring]) // Pogo Spring minimum/maximum thrust
@ -3414,7 +3417,7 @@ void K_SpawnDraftDust(mobj_t *mo)
ang = mo->player->frameangle; ang = mo->player->frameangle;
if (mo->player->kartstuff[k_drift] != 0) if (mo->player->kartstuff[k_drift] != 0)
{ {
drifting = true; drifting = true;
ang += (mo->player->kartstuff[k_drift] * ((ANGLE_270 + ANGLE_22h) / 5)); // -112.5 doesn't work. I fucking HATE SRB2 angles ang += (mo->player->kartstuff[k_drift] * ((ANGLE_270 + ANGLE_22h) / 5)); // -112.5 doesn't work. I fucking HATE SRB2 angles
@ -4526,6 +4529,15 @@ static void K_MoveHeldObjects(player_t *player)
if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT) if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT)
P_TeleportMove(cur, targx, targy, cur->z); P_TeleportMove(cur, targx, targy, cur->z);
#ifdef ESLOPE
if (P_IsObjectOnGround(cur))
{
// Slope values are set in the function, but we DON'T want to use its return value.
P_CalculateShadowFloor(cur, cur->x, cur->y, cur->z,
cur->radius, cur->height, (cur->eflags & MFE_VERTICALFLIP), false);
}
#endif
cur = cur->hnext; cur = cur->hnext;
} }
} }
@ -4615,6 +4627,9 @@ static void K_MoveHeldObjects(player_t *player)
P_TeleportMove(cur, targx, targy, targz); P_TeleportMove(cur, targx, targy, targz);
K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks. K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks.
#ifdef HWRENDER
cur->modeltilt = player->mo->modeltilt;
#endif
num = (num+1) % 2; num = (num+1) % 2;
cur = cur->hnext; cur = cur->hnext;
} }
@ -5058,6 +5073,29 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (P_IsDisplayPlayer(player)) if (P_IsDisplayPlayer(player))
debtflag->flags2 |= MF2_DONTDRAW; 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 if (player->playerstate == PST_DEAD || player->kartstuff[k_respawn] > 1) // Ensure these are set correctly here
@ -5260,6 +5298,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->kartstuff[k_justbumped]) if (player->kartstuff[k_justbumped])
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 // This doesn't go in HUD update because it has potential gameplay ramifications
if (player->karthud[khud_itemblink] && player->karthud[khud_itemblink]-- <= 0) if (player->karthud[khud_itemblink] && player->karthud[khud_itemblink]-- <= 0)
{ {
@ -5300,17 +5341,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]) if (player->kartstuff[k_comebacktimer])
player->kartstuff[k_comebackmode] = 0; player->kartstuff[k_comebackmode] = 0;
@ -5440,15 +5470,16 @@ static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer)
return 0; return 0;
if (player->kartstuff[k_driftend] != 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 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 = 90*player->kartstuff[k_drift]; // 450
//basedrift = 93*player->kartstuff[k_drift] - driftweight*3*player->kartstuff[k_drift]/10; // 447 - 303 //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 basedrift = 83*player->kartstuff[k_drift] - (driftweight - 14)*player->kartstuff[k_drift]/5; // 415 - 303
driftangle = abs((252 - driftweight)*player->kartstuff[k_drift]/5); 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); return basedrift + FixedMul(driftangle, countersteer);
} }
@ -5922,7 +5953,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
&& NO_HYUDORO && !(HOLDING_ITEM && NO_HYUDORO && !(HOLDING_ITEM
|| player->kartstuff[k_itemamount] || player->kartstuff[k_itemamount]
|| player->kartstuff[k_itemroulette] || 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_rocketsneakertimer]
|| player->kartstuff[k_eggmanexplode])) || player->kartstuff[k_eggmanexplode]))
player->kartstuff[k_userings] = 1; player->kartstuff[k_userings] = 1;
@ -6490,6 +6521,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (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 // Friction
if (!player->kartstuff[k_offroad]) if (!player->kartstuff[k_offroad])
{ {
@ -6502,9 +6539,20 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
// Karma ice physics // Karma ice physics
if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0)
{
player->mo->friction += 1228; 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) if (player->mo->friction > FRACUNIT)
player->mo->friction = FRACUNIT; player->mo->friction = FRACUNIT;
if (player->mo->friction < 0) if (player->mo->friction < 0)
@ -6515,20 +6563,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->mo->movefactor < FRACUNIT) if (player->mo->movefactor < FRACUNIT)
player->mo->movefactor = 19*player->mo->movefactor - 18*FRACUNIT; player->mo->movefactor = 19*player->mo->movefactor - 18*FRACUNIT;
else else
player->mo->movefactor = FRACUNIT; //player->mo->movefactor = ((player->mo->friction - 0xDB34)*(0xA))/0x80; player->mo->movefactor = FRACUNIT;
if (player->mo->movefactor < 32) if (player->mo->movefactor < 32)
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, onground);
@ -9560,7 +9599,7 @@ void K_drawKartFreePlay(UINT32 flashtime)
return; return;
V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - (12*9), // mirror the laps thingy 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) static void K_drawDistributionDebugger(void)

View file

@ -1405,15 +1405,15 @@ static int lib_pIsFlagAtBase(lua_State *L)
static int lib_pSetupLevelSky(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; player_t *user = NULL;
NOHUD 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 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)); user = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
if (!user) // global if (!user) // global
P_SetupLevelSky(skynum, true); P_SetupLevelSky(skytexname, true);
else if (P_IsLocalPlayer(user)) else if (P_IsLocalPlayer(user))
P_SetupLevelSky(skynum, false); P_SetupLevelSky(skytexname, false);
return 0; return 0;
} }

View file

@ -1487,8 +1487,8 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushstring(L, header->forcecharacter); lua_pushstring(L, header->forcecharacter);
else if (fastcmp(field,"weather")) else if (fastcmp(field,"weather"))
lua_pushinteger(L, header->weather); lua_pushinteger(L, header->weather);
else if (fastcmp(field,"skynum")) else if (fastcmp(field,"skytexture"))
lua_pushinteger(L, header->skynum); lua_pushstring(L, header->skytexture);
else if (fastcmp(field,"skybox_scalex")) else if (fastcmp(field,"skybox_scalex"))
lua_pushinteger(L, header->skybox_scalex); lua_pushinteger(L, header->skybox_scalex);
else if (fastcmp(field,"skybox_scaley")) else if (fastcmp(field,"skybox_scaley"))

View file

@ -422,7 +422,7 @@ static void GIF_headwrite(void)
WRITEUINT16(p, rheight); WRITEUINT16(p, rheight);
// colors, aspect, etc // colors, aspect, etc
WRITEUINT8(p, 0xF7); WRITEUINT8(p, 0xFF); // TRANSPARENTPIXEL
WRITEUINT8(p, 0x00); WRITEUINT8(p, 0x00);
WRITEUINT8(p, 0x00); WRITEUINT8(p, 0x00);

View file

@ -577,14 +577,14 @@ void Command_Skynum_f(void)
if (COM_Argc() != 2) if (COM_Argc() != 2)
{ {
CONS_Printf(M_GetText("skynum <sky#>: change the sky\n")); CONS_Printf(M_GetText("skynum <texture name>: change the sky\n"));
CONS_Printf(M_GetText("Current sky is %d\n"), levelskynum); CONS_Printf(M_GetText("Current sky is %s\n"), levelskytexture);
return; return;
} }
CONS_Printf(M_GetText("Previewing sky %s...\n"), COM_Argv(1)); 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) void Command_Weather_f(void)

View file

@ -522,7 +522,7 @@ static menuitem_t PlaybackMenu[] =
{IT_CALL | IT_STRING, "M_PREW", "Rewind", M_PlaybackRewind, 20}, {IT_CALL | IT_STRING, "M_PREW", "Rewind", M_PlaybackRewind, 20},
{IT_CALL | IT_STRING, "M_PPAUSE", "Pause", M_PlaybackPause, 36}, {IT_CALL | IT_STRING, "M_PPAUSE", "Pause", M_PlaybackPause, 36},
{IT_CALL | IT_STRING, "M_PFFWD", "Fast-Foward", M_PlaybackFastForward, 52}, {IT_CALL | IT_STRING, "M_PFFWD", "Fast-Forward", M_PlaybackFastForward, 52},
{IT_CALL | IT_STRING, "M_PSTEPB", "Backup Frame", M_PlaybackRewind, 20}, {IT_CALL | IT_STRING, "M_PSTEPB", "Backup Frame", M_PlaybackRewind, 20},
{IT_CALL | IT_STRING, "M_PRESUM", "Resume", M_PlaybackPause, 36}, {IT_CALL | IT_STRING, "M_PRESUM", "Resume", M_PlaybackPause, 36},
{IT_CALL | IT_STRING, "M_PFADV", "Advance Frame", M_PlaybackAdvance, 52}, {IT_CALL | IT_STRING, "M_PFADV", "Advance Frame", M_PlaybackAdvance, 52},
@ -8433,7 +8433,11 @@ static void M_ConnectMenu(INT32 choice)
// first page of servers // first page of servers
serverlistpage = 0; serverlistpage = 0;
if (ms_RoomId < 0) if (ms_RoomId < 0)
{
M_RoomMenu(0); // Select a room instead of staring at an empty list M_RoomMenu(0); // Select a room instead of staring at an empty list
// This prevents us from returning to the modified game alert.
currentMenu->prevMenu = &MP_MainDef;
}
else else
M_SetupNextMenu(&MP_ConnectDef); M_SetupNextMenu(&MP_ConnectDef);
itemOn = 0; itemOn = 0;

View file

@ -661,19 +661,11 @@ FUNCMATH static const char *int2str(INT32 n)
#ifndef NONET #ifndef NONET
static INT32 ConnectionFailed(void) static INT32 ConnectionFailed(void)
{ {
time(&MSLastPing);
con_state = MSCS_FAILED; con_state = MSCS_FAILED;
CONS_Alert(CONS_ERROR, M_GetText("Connection to Master Server failed\n")); CONS_Alert(CONS_ERROR, M_GetText("Connection to Master Server failed\n"));
CloseConnection(); CloseConnection();
return MS_CONNECT_ERROR; return MS_CONNECT_ERROR;
} }
static INT32 ConnectionFailedwerrno(int no)
{
CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error: %s\n"),
strerror(no));
return ConnectionFailed();
}
#endif #endif
/** Tries to register the local game server on the master server. /** Tries to register the local game server on the master server.
@ -690,43 +682,57 @@ static INT32 AddToMasterServer(boolean firstadd)
msg_server_t *info = (msg_server_t *)msg.buffer; msg_server_t *info = (msg_server_t *)msg.buffer;
INT32 room = -1; INT32 room = -1;
fd_set tset; fd_set tset;
time_t timestamp = time(NULL);
UINT32 signature, tmp; UINT32 signature, tmp;
const char *insname; const char *insname;
if (socket_fd == (SOCKET_TYPE)ERRSOCKET)/* Woah, our socket was closed! */
{
if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0))
return ConnectionFailedwerrno(errno);
}
M_Memcpy(&tset, &wset, sizeof (tset)); M_Memcpy(&tset, &wset, sizeof (tset));
res = select(255, NULL, &tset, NULL, &select_timeout); res = select(255, NULL, &tset, NULL, &select_timeout);
if (res == ERRSOCKET) if (res != ERRSOCKET && !res)
return ConnectionFailedwerrno(errno);
if (res == 0)/* nothing selected */
{ {
/* if (retry++ > 30) // an about 30 second timeout
Timeout next call because SendPingToMasterServer
(our calling function) already calls this once
every two minutes.
*/
if (retry++ == 1)
{ {
retry = 0; retry = 0;
CONS_Alert(CONS_ERROR, M_GetText("Master Server timed out\n")); CONS_Alert(CONS_ERROR, M_GetText("Master Server timed out\n"));
MSLastPing = timestamp;
return ConnectionFailed(); return ConnectionFailed();
} }
return MS_CONNECT_ERROR; return MS_CONNECT_ERROR;
} }
retry = 0; retry = 0;
/*
Somehow we can still select our old socket despite it being closed(?).
Atleast, that's what I THINK is happening. Anyway, we have to check that we
haven't open a socket, and actually open it!
*/
/*if (res == ERRSOCKET)*//* wtf? no! */
if (socket_fd == (SOCKET_TYPE)ERRSOCKET)
{
if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0))
{
CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error #%u: %s\n"), errno, strerror(errno));
MSLastPing = timestamp;
return ConnectionFailed();
}
}
// so, the socket is writable, but what does that mean, that the connection is // so, the socket is writable, but what does that mean, that the connection is
// ok, or bad... let see that! // ok, or bad... let see that!
j = (socklen_t)sizeof (i); j = (socklen_t)sizeof (i);
if (getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, (char *)&i, &j) == ERRSOCKET) getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, (char *)&i, &j);
return ConnectionFailedwerrno(errno); /*
This is also wrong. If getsockopt fails, i doesn't have to be set. Plus, if
it is set (which it appearantly is on linux), we check errno anyway. And in
the case that i is returned as normal, we don't even report the correct
value! So we accomplish NOTHING, except returning due to dumb luck.
If you care, fix this--I don't. -James (R.)
*/
if (i) // it was bad if (i) // it was bad
return ConnectionFailedwerrno(i); {
CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error #%u: %s\n"), errno, strerror(errno));
MSLastPing = timestamp;
return ConnectionFailed();
}
#ifdef PARANOIA #ifdef PARANOIA
if (ms_RoomId <= 0) if (ms_RoomId <= 0)
@ -759,12 +765,15 @@ static INT32 AddToMasterServer(boolean firstadd)
msg.length = (UINT32)sizeof (msg_server_t); msg.length = (UINT32)sizeof (msg_server_t);
msg.room = 0; msg.room = 0;
if (MS_Write(&msg) < 0) if (MS_Write(&msg) < 0)
{
MSLastPing = timestamp;
return ConnectionFailed(); return ConnectionFailed();
}
if(con_state != MSCS_REGISTERED) if(con_state != MSCS_REGISTERED)
CONS_Printf(M_GetText("Master Server update successful.\n")); CONS_Printf(M_GetText("Master Server update successful.\n"));
time(&MSLastPing); MSLastPing = timestamp;
con_state = MSCS_REGISTERED; con_state = MSCS_REGISTERED;
CloseConnection(); CloseConnection();
#endif #endif

View file

@ -3558,6 +3558,8 @@ void A_BubbleCheck(mobj_t *actor)
// //
void A_AttractChase(mobj_t *actor) void A_AttractChase(mobj_t *actor)
{ {
fixed_t z;
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (LUA_CallAction("A_AttractChase", actor)) if (LUA_CallAction("A_AttractChase", actor))
return; return;
@ -3601,7 +3603,12 @@ void A_AttractChase(mobj_t *actor)
{ {
fixed_t offz = FixedMul(80*actor->target->scale, FINESINE(FixedAngle((90 - (9 * abs(10 - actor->extravalue1))) << FRACBITS) >> ANGLETOFINESHIFT)); 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)); //P_SetScale(actor, (actor->destscale = actor->target->scale));
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z + actor->target->height + offz); 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->extravalue1++; actor->extravalue1++;
} }
} }
@ -3628,10 +3635,15 @@ void A_AttractChase(mobj_t *actor)
fixed_t dist = (actor->target->radius/4) * (16 - actor->extravalue1); fixed_t dist = (actor->target->radius/4) * (16 - actor->extravalue1);
P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * 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;
P_TeleportMove(actor, P_TeleportMove(actor,
actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)), actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)),
actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)), actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)),
actor->target->z + (24 * actor->target->scale)); z);
actor->angle += ANG30; actor->angle += ANG30;
actor->extravalue1++; actor->extravalue1++;
@ -8309,7 +8321,11 @@ void A_ItemPop(mobj_t *actor)
void A_JawzChase(mobj_t *actor) void A_JawzChase(mobj_t *actor)
{ {
const fixed_t currentspeed = R_PointToDist2(0, 0, actor->momx, actor->momy);
player_t *player; player_t *player;
fixed_t thrustamount = 0;
fixed_t frictionsafety = (actor->friction == 0) ? 1 : actor->friction;
fixed_t topspeed = actor->movefactor;
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (LUA_CallAction("A_JawzChase", actor)) if (LUA_CallAction("A_JawzChase", actor))
return; return;
@ -8322,20 +8338,100 @@ void A_JawzChase(mobj_t *actor)
if (actor->tracer->health) if (actor->tracer->health)
{ {
const angle_t targetangle = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y);
mobj_t *ret; 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); ret = P_SpawnMobj(actor->tracer->x, actor->tracer->y, actor->tracer->z, MT_PLAYERRETICULE);
P_SetTarget(&ret->target, actor->tracer); P_SetTarget(&ret->target, actor->tracer);
ret->frame |= ((leveltime % 10) / 2) + 5; ret->frame |= ((leveltime % 10) / 2) + 5;
ret->color = actor->cvmem; 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 else
P_SetTarget(&actor->tracer, NULL); 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 if (actor->extravalue1) // Disable looking by setting this
return; return;

View file

@ -3306,12 +3306,12 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
// 20 is the ring cap in kart // 20 is the ring cap in kart
if (num_rings > 20) if (num_rings > 20)
num_rings = 20; num_rings = 20;
else if (num_rings <= 0) else if (num_rings <= 0)
return; return;
// Cap the maximum loss automatically to 2 in ring debt // Cap the maximum loss automatically to 2 in ring debt
if (player->kartstuff[k_rings] <= 0 && num_rings > 2) if (player->kartstuff[k_rings] <= 0 && num_rings > 2)
num_rings = 2; num_rings = 2;
P_GivePlayerRings(player, -num_rings); P_GivePlayerRings(player, -num_rings);

View file

@ -227,6 +227,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
boolean P_SetMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
//void P_RunShields(void); //void P_RunShields(void);
void P_RunOverlays(void); void P_RunOverlays(void);
fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player);
void P_RunShadows(void); void P_RunShadows(void);
void P_MobjThinker(mobj_t *mobj); void P_MobjThinker(mobj_t *mobj);
boolean P_RailThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj);

View file

@ -113,14 +113,18 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
// MOVEMENT ITERATOR FUNCTIONS // MOVEMENT ITERATOR FUNCTIONS
// ========================================================================= // =========================================================================
//#define TELEPORTJANK
boolean P_DoSpring(mobj_t *spring, mobj_t *object) boolean P_DoSpring(mobj_t *spring, mobj_t *object)
{ {
//INT32 pflags; //INT32 pflags;
const fixed_t hscale = mapobjectscale + (mapobjectscale - object->scale); const fixed_t hscale = mapobjectscale + (mapobjectscale - object->scale);
const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale); const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale);
fixed_t offx, offy;
fixed_t vertispeed = spring->info->mass; fixed_t vertispeed = spring->info->mass;
fixed_t horizspeed = spring->info->damage; 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 if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
return false; return false;
@ -142,29 +146,36 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
object->eflags |= MFE_SPRUNG; // apply this flag asap! object->eflags |= MFE_SPRUNG; // apply this flag asap!
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
#ifdef TELEPORTJANK
if (horizspeed && vertispeed) // Mimic SA if (horizspeed && vertispeed) // Mimic SA
{ {
object->momx = object->momy = 0; object->momx = object->momy = 0;
P_TryMove(object, spring->x, spring->y, true); P_TryMove(object, spring->x, spring->y, true);
} }
#endif
if (spring->eflags & MFE_VERTICALFLIP) if (spring->eflags & MFE_VERTICALFLIP)
vertispeed *= -1; vertispeed *= -1;
// Vertical springs teleport you on TOP of them.
if (vertispeed > 0) if (vertispeed > 0)
object->z = spring->z + spring->height + 1; object->z = spring->z + spring->height + 1;
else if (vertispeed < 0) else if (vertispeed < 0)
object->z = spring->z - object->height - 1; object->z = spring->z - object->height - 1;
else else
{ {
fixed_t offx, offy;
// Horizontal springs teleport you in FRONT of them. // Horizontal springs teleport you in FRONT of them.
savemomx = object->momx;
savemomy = object->momy;
object->momx = object->momy = 0; object->momx = object->momy = 0;
// Overestimate the distance to position you at // Overestimate the distance to position you at
offx = P_ReturnThrustX(spring, spring->angle, (spring->radius + object->radius + 1) * 2); offx = P_ReturnThrustX(spring, spring->angle, (spring->radius + object->radius + 1) * 2);
offy = P_ReturnThrustY(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)) if (offx > (spring->radius + object->radius + 1))
offx = spring->radius + object->radius + 1; offx = spring->radius + object->radius + 1;
else if (offx < -(spring->radius + object->radius + 1)) else if (offx < -(spring->radius + object->radius + 1))
@ -175,27 +186,94 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
else if (offy < -(spring->radius + object->radius + 1)) else if (offy < -(spring->radius + object->radius + 1))
offy = -(spring->radius + object->radius + 1); offy = -(spring->radius + object->radius + 1);
// Set position!
P_TryMove(object, spring->x + offx, spring->y + offy, true); P_TryMove(object, spring->x + offx, spring->y + offy, true);
} }
if (vertispeed) if (vertispeed)
object->momz = FixedMul(vertispeed,FixedSqrt(FixedMul(vscale, spring->scale))); object->momz = FixedMul(vertispeed, FixedSqrt(FixedMul(vscale, spring->scale)));
if (horizspeed) if (horizspeed)
{ {
if (!object->player) angle_t finalAngle = spring->angle;
P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(horizspeed,FixedSqrt(FixedMul(hscale, spring->scale)))); fixed_t finalSpeed = horizspeed;
fixed_t objectSpeed;
if (object->player)
objectSpeed = object->player->speed;
else else
objectSpeed = R_PointToDist2(0, 0, savemomx, savemomy);
if (!vertispeed)
{ {
fixed_t finalSpeed = FixedDiv(horizspeed, hscale); // Scale to gamespeed
fixed_t pSpeed = object->player->speed; finalSpeed = FixedMul(finalSpeed, K_GetKartGameSpeedScalar(gamespeed));
if (pSpeed > finalSpeed) // Reflect your momentum angle against the surface of horizontal springs.
finalSpeed = pSpeed; // 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 // Re-solidify
@ -208,46 +286,12 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (spring->flags & MF_ENEMY) // Spring shells if (spring->flags & MF_ENEMY) // Spring shells
P_SetTarget(&spring->target, object); 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); P_ResetPlayer(object->player);
/* // SRB2kart - Springs don't need to change player state in kart. object->player->kartstuff[k_springstars] = max(vertispeed, horizspeed) / FRACUNIT / 2;
if (P_MobjFlip(object)*vertispeed > 0) object->player->kartstuff[k_springcolor] = starcolor;
P_SetPlayerMobjState(object, S_PLAY_SPRING);
else if (P_MobjFlip(object)*vertispeed < 0)
P_SetPlayerMobjState(object, S_PLAY_FALL1);
else // horizontal spring
{
if (pflags & (PF_JUMPED|PF_SPINNING) && object->player->panim == PA_ROLL)
object->player->pflags = pflags;
else
P_SetPlayerMobjState(object, S_PLAY_RUN1);
}
if (spring->info->painchance)
{
object->player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(object, S_PLAY_ATK1);
}
*/
} }
return true; return true;
} }
@ -1163,6 +1207,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
//else if (tmz > thzh - sprarea && tmz < thzh) // Don't damage people springing up / down //else if (tmz > thzh - sprarea && tmz < thzh) // Don't damage people springing up / down
return true; return true;
} }
// missiles can hit other things // missiles can hit other things
if (tmthing->flags & MF_MISSILE || tmthing->type == MT_SHELL) if (tmthing->flags & MF_MISSILE || tmthing->type == MT_SHELL)
{ {
@ -2892,14 +2937,24 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
P_HandleSlopeLanding(thing, tmfloorslope); P_HandleSlopeLanding(thing, tmfloorslope);
if (thing->momz <= 0) if (thing->momz <= 0)
{
thing->standingslope = tmfloorslope; thing->standingslope = tmfloorslope;
#ifdef HWRENDER
thing->modeltilt = thing->standingslope;
#endif
}
} }
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
if (!startingonground && tmceilingslope) if (!startingonground && tmceilingslope)
P_HandleSlopeLanding(thing, tmceilingslope); P_HandleSlopeLanding(thing, tmceilingslope);
if (thing->momz >= 0) if (thing->momz >= 0)
{
thing->standingslope = tmceilingslope; thing->standingslope = tmceilingslope;
#ifdef HWRENDER
thing->modeltilt = thing->standingslope;
#endif
}
} }
} }
else // don't set standingslope if you're not going to clip against it else // don't set standingslope if you're not going to clip against it
@ -4702,7 +4757,7 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; 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; continue;
topheight = *rover->topheight; topheight = *rover->topheight;

View file

@ -1848,6 +1848,9 @@ void P_XYMovement(mobj_t *mo)
// Now compare the Zs of the different quantizations // Now compare the Zs of the different quantizations
if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later
mo->standingslope = oldslope; mo->standingslope = oldslope;
#ifdef HWRENDER
mo->modeltilt = mo->standingslope;
#endif
P_SlopeLaunch(mo); P_SlopeLaunch(mo);
//CONS_Printf("launched off of slope - "); //CONS_Printf("launched off of slope - ");
@ -1937,7 +1940,7 @@ void P_XYMovement(mobj_t *mo)
#endif #endif
//{ SRB2kart stuff //{ SRB2kart stuff
if (mo->type == MT_ORBINAUT || mo->type == MT_JAWZ_DUD || mo->type == MT_JAWZ || mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer)) if (mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer))
return; return;
if (mo->player && (mo->player->kartstuff[k_spinouttimer] && !mo->player->kartstuff[k_wipeoutslow]) && mo->player->speed <= K_GetKartSpeed(mo->player, false)/2) if (mo->player && (mo->player->kartstuff[k_spinouttimer] && !mo->player->kartstuff[k_wipeoutslow]) && mo->player->speed <= K_GetKartSpeed(mo->player, false)/2)
@ -2421,6 +2424,9 @@ static boolean P_ZMovement(mobj_t *mo)
if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
{ {
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
#ifdef HWRENDER
mo->modeltilt = mo->standingslope;
#endif
P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
} }
#endif #endif
@ -6199,13 +6205,178 @@ static void P_RemoveOverlay(mobj_t *thing)
} }
} }
// Simplified version of a code bit in P_MobjFloorZ
static fixed_t P_ShadowSlopeZ(pslope_t *slope, fixed_t x, fixed_t y, fixed_t radius, boolean ceiling)
{
fixed_t testx, testy;
if (slope->d.x < 0)
testx = radius;
else
testx = -radius;
if (slope->d.y < 0)
testy = radius;
else
testy = -radius;
if ((slope->zdelta > 0) ^ !!(ceiling))
{
testx = -testx;
testy = -testy;
}
testx += x;
testy += y;
return P_GetZAt(slope, testx, testy);
}
// Sets standingslope/modeltilt, returns z position for shadows; used also for stuff like bananas
// (I would've preferred to be able to return both the slope & z, but I'll take what I can get...)
fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player)
{
fixed_t newz;
sector_t *sec;
#ifdef ESLOPE
pslope_t *slope = NULL;
#endif
sec = R_PointInSubsector(x, y)->sector;
if (flip)
{
#ifdef ESLOPE
if (sec->c_slope)
{
slope = sec->c_slope;
newz = P_ShadowSlopeZ(slope, x, y, radius, true);
}
else
#endif
newz = sec->ceilingheight;
}
else
{
#ifdef ESLOPE
if (sec->f_slope)
{
slope = sec->f_slope;
newz = P_ShadowSlopeZ(slope, x, y, radius, false);
}
else
#endif
newz = sec->floorheight;
}
// Check FOFs for a better suited slope
if (sec->ffloors)
{
ffloor_t *rover;
for (rover = sec->ffloors; rover; rover = rover->next)
{
fixed_t top, bottom;
fixed_t d1, d2;
if (!(rover->flags & FF_EXISTS))
continue;
if ((!(((rover->flags & FF_BLOCKPLAYER && player)
|| (rover->flags & FF_BLOCKOTHERS && !player))
|| (rover->flags & FF_QUICKSAND))
|| (rover->flags & FF_SWIMMABLE)))
continue;
#ifdef ESLOPE
if (*rover->t_slope)
top = P_ShadowSlopeZ(*rover->t_slope, x, y, radius, false);
else
#endif
top = *rover->topheight;
#ifdef ESLOPE
if (*rover->b_slope)
bottom = P_ShadowSlopeZ(*rover->b_slope, x, y, radius, true);
else
#endif
bottom = *rover->bottomheight;
if (flip)
{
if (rover->flags & FF_QUICKSAND)
{
if (z < top && (z + height) > bottom)
{
if (newz > (z + height))
{
newz = (z + height);
slope = NULL;
}
}
continue;
}
d1 = (z + height) - (top + ((bottom - top)/2));
d2 = z - (top + ((bottom - top)/2));
if (bottom < newz && abs(d1) < abs(d2))
{
newz = bottom;
#ifdef ESLOPE
if (*rover->b_slope)
slope = *rover->b_slope;
#endif
}
}
else
{
if (rover->flags & FF_QUICKSAND)
{
if (z < top && (z + height) > bottom)
{
if (newz < z)
{
newz = z;
slope = NULL;
}
}
continue;
}
d1 = z - (bottom + ((top - bottom)/2));
d2 = (z + height) - (bottom + ((top - bottom)/2));
if (top > newz && abs(d1) < abs(d2))
{
newz = top;
#ifdef ESLOPE
if (*rover->t_slope)
slope = *rover->t_slope;
#endif
}
}
}
}
#if 0
mobj->standingslope = slope;
#endif
#ifdef HWRENDER
mobj->modeltilt = slope;
#endif
return newz;
}
void P_RunShadows(void) void P_RunShadows(void)
{ {
mobj_t *mobj, *next, *dest; mobj_t *mobj, *next, *dest;
for (mobj = shadowcap; mobj; mobj = next) for (mobj = shadowcap; mobj; mobj = next)
{ {
fixed_t floorz; boolean flip;
fixed_t newz;
next = mobj->hnext; next = mobj->hnext;
P_SetTarget(&mobj->hnext, NULL); P_SetTarget(&mobj->hnext, NULL);
@ -6216,16 +6387,22 @@ void P_RunShadows(void)
continue; // shouldn't you already be dead? continue; // shouldn't you already be dead?
} }
if (mobj->target->player)
floorz = mobj->target->floorz;
else // FOR SOME REASON, plain floorz is not reliable for normal objects, only players?!
floorz = P_FloorzAtPos(mobj->target->x, mobj->target->y, mobj->target->z, mobj->target->height);
K_MatchGenericExtraFlags(mobj, mobj->target); K_MatchGenericExtraFlags(mobj, mobj->target);
flip = (mobj->eflags & MFE_VERTICALFLIP);
if (((mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z+mobj->target->height > mobj->target->ceilingz) newz = P_CalculateShadowFloor(mobj, mobj->target->x, mobj->target->y, mobj->target->z,
|| (!(mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z < floorz)) mobj->target->radius, mobj->target->height, flip, (mobj->target->player != NULL));
mobj->flags2 |= MF2_DONTDRAW;
if (flip)
{
if ((mobj->target->z + mobj->target->height) > newz)
mobj->flags2 |= MF2_DONTDRAW;
}
else
{
if (mobj->target->z < newz)
mobj->flags2 |= MF2_DONTDRAW;
}
// First scale to the same radius // First scale to the same radius
P_SetScale(mobj, FixedDiv(mobj->target->radius, mobj->info->radius)); P_SetScale(mobj, FixedDiv(mobj->target->radius, mobj->info->radius));
@ -6237,13 +6414,12 @@ void P_RunShadows(void)
P_TeleportMove(mobj, dest->x, dest->y, mobj->target->z); P_TeleportMove(mobj, dest->x, dest->y, mobj->target->z);
if (((mobj->eflags & MFE_VERTICALFLIP) && (mobj->ceilingz > mobj->z+mobj->height)) if ((flip && newz > (mobj->z + mobj->height)) || (!flip && newz < mobj->z))
|| (!(mobj->eflags & MFE_VERTICALFLIP) && (floorz < mobj->z)))
{ {
INT32 i; INT32 i;
fixed_t prevz; fixed_t prevz;
mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : floorz); mobj->z = newz;
for (i = 0; i < MAXFFLOORS; i++) for (i = 0; i < MAXFFLOORS; i++)
{ {
@ -6255,7 +6431,7 @@ void P_RunShadows(void)
// Check new position to see if you should still be on that ledge // Check new position to see if you should still be on that ledge
P_TeleportMove(mobj, dest->x, dest->y, mobj->z); P_TeleportMove(mobj, dest->x, dest->y, mobj->z);
mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : floorz); mobj->z = newz;
if (mobj->z == prevz) if (mobj->z == prevz)
break; break;
@ -7935,9 +8111,18 @@ void P_MobjThinker(mobj_t *mobj)
else else
{ {
fixed_t finalspeed = mobj->movefactor; fixed_t finalspeed = mobj->movefactor;
const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy);
fixed_t thrustamount = 0;
fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction;
mobj_t *ghost = P_SpawnGhostMobj(mobj); mobj_t *ghost = P_SpawnGhostMobj(mobj);
ghost->colorized = true; // already has color! ghost->colorized = true; // already has color!
if (!grounded)
{
// No friction in the air
frictionsafety = FRACUNIT;
}
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
if (mobj->health <= 5) if (mobj->health <= 5)
{ {
@ -7946,7 +8131,19 @@ void P_MobjThinker(mobj_t *mobj)
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
} }
P_InstaThrust(mobj, mobj->angle, finalspeed); if (currentspeed >= finalspeed)
{
// Thrust as if you were at top speed, slow down naturally
thrustamount = FixedDiv(finalspeed, frictionsafety) - finalspeed;
}
else
{
const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed;
// Thrust to immediately get to top speed
thrustamount = beatfriction + FixedDiv(finalspeed - currentspeed, frictionsafety);
}
P_Thrust(mobj, mobj->angle, thrustamount);
if (grounded) if (grounded)
{ {
@ -7968,9 +8165,6 @@ void P_MobjThinker(mobj_t *mobj)
case MT_JAWZ: case MT_JAWZ:
{ {
sector_t *sec2; sector_t *sec2;
fixed_t topspeed = mobj->movefactor;
fixed_t distbarrier = 512*mapobjectscale;
fixed_t distaway;
mobj_t *ghost = P_SpawnGhostMobj(mobj); mobj_t *ghost = P_SpawnGhostMobj(mobj);
if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player)
@ -7984,37 +8178,7 @@ void P_MobjThinker(mobj_t *mobj)
if (leveltime % TICRATE == 0) if (leveltime % TICRATE == 0)
S_StartSound(mobj, mobj->info->activesound); S_StartSound(mobj, mobj->info->activesound);
distbarrier = FixedMul(distbarrier, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4))); // Movement handling has ALL been moved to A_JawzChase
if (G_RaceGametype() && mobj->tracer)
{
distaway = P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y);
if (distaway < distbarrier)
{
if (mobj->tracer->player)
{
fixed_t speeddifference = abs(topspeed - min(mobj->tracer->player->speed, K_GetKartSpeed(mobj->tracer->player, false)));
topspeed = topspeed - FixedMul(speeddifference, FRACUNIT-FixedDiv(distaway, distbarrier));
}
}
}
if (G_BattleGametype())
{
mobj->friction -= 1228;
if (mobj->friction > FRACUNIT)
mobj->friction = FRACUNIT;
if (mobj->friction < 0)
mobj->friction = 0;
}
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
P_InstaThrust(mobj, mobj->angle, topspeed);
if (mobj->tracer)
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y);
else
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
K_DriftDustHandling(mobj); K_DriftDustHandling(mobj);
@ -8042,6 +8206,9 @@ void P_MobjThinker(mobj_t *mobj)
else else
{ {
mobj_t *ghost = P_SpawnGhostMobj(mobj); mobj_t *ghost = P_SpawnGhostMobj(mobj);
const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy);
fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction;
fixed_t thrustamount = 0;
if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player)
{ {
@ -8049,8 +8216,26 @@ void P_MobjThinker(mobj_t *mobj)
ghost->colorized = true; ghost->colorized = true;
} }
if (!grounded)
{
// No friction in the air
frictionsafety = FRACUNIT;
}
if (currentspeed >= mobj->movefactor)
{
// Thrust as if you were at top speed, slow down naturally
thrustamount = FixedDiv(mobj->movefactor, frictionsafety) - mobj->movefactor;
}
else
{
const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed;
// Thrust to immediately get to top speed
thrustamount = beatfriction + FixedDiv(mobj->movefactor - currentspeed, frictionsafety);
}
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
P_InstaThrust(mobj, mobj->angle, mobj->movefactor); P_Thrust(mobj, mobj->angle, thrustamount);
if (grounded) if (grounded)
{ {
@ -8207,6 +8392,9 @@ void P_MobjThinker(mobj_t *mobj)
P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius), P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z); mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
P_SetScale(mobj, mobj->target->scale); P_SetScale(mobj, mobj->target->scale);
#ifdef HWRENDER
mobj->modeltilt = mobj->target->modeltilt;
#endif
{ {
player_t *p = NULL; player_t *p = NULL;
@ -8347,9 +8535,67 @@ void P_MobjThinker(mobj_t *mobj)
} }
K_MatchGenericExtraFlags(mobj, mobj->target); K_MatchGenericExtraFlags(mobj, mobj->target);
P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT), {
mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT), fixed_t z;
mobj->target->z + mobj->target->height); z = mobj->target->z;
if (( mobj->eflags & MFE_VERTICALFLIP ))
z -= mobj->height;
else
z += mobj->target->height;
P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT),
mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT),
z);
}
break;
case MT_TIREGREASE:
if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->player
|| !mobj->target->player->kartstuff[k_tiregrease])
{
P_RemoveMobj(mobj);
return;
}
K_MatchGenericExtraFlags(mobj, mobj->target);
{
const angle_t off = FixedAngle(40*FRACUNIT);
angle_t ang = mobj->target->angle;
fixed_t z;
UINT8 trans = (mobj->target->player->kartstuff[k_tiregrease] * (NUMTRANSMAPS+1)) / greasetics;
if (trans > NUMTRANSMAPS)
trans = NUMTRANSMAPS;
trans = NUMTRANSMAPS - trans;
z = mobj->target->z;
if (mobj->eflags & MFE_VERTICALFLIP)
z += mobj->target->height;
if (mobj->target->momx || mobj->target->momy)
ang = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy);
if (mobj->extravalue1)
ang = (signed)(ang - off);
else
ang = (signed)(ang + off);
P_TeleportMove(mobj,
mobj->target->x - FixedMul(mobj->target->radius, FINECOSINE(ang >> ANGLETOFINESHIFT)),
mobj->target->y - FixedMul(mobj->target->radius, FINESINE(ang >> ANGLETOFINESHIFT)),
z);
mobj->angle = ang;
if (leveltime & 1)
mobj->flags2 |= MF2_DONTDRAW;
if (trans >= NUMTRANSMAPS)
mobj->flags2 |= MF2_DONTDRAW;
else if (trans == 0)
mobj->frame = (mobj->frame & ~FF_TRANSMASK);
else
mobj->frame = (mobj->frame & ~FF_TRANSMASK)|(trans << FF_TRANSSHIFT);
}
break; break;
case MT_THUNDERSHIELD: case MT_THUNDERSHIELD:
{ {
@ -9053,6 +9299,9 @@ void P_MobjThinker(mobj_t *mobj)
} }
break; break;
case MT_KARMAFIREWORK: case MT_KARMAFIREWORK:
if (mobj->flags & MF_NOGRAVITY)
break;
if (mobj->momz == 0) if (mobj->momz == 0)
{ {
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
@ -9439,7 +9688,9 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
|| mobj->type == MT_BIGTUMBLEWEED || mobj->type == MT_BIGTUMBLEWEED
|| mobj->type == MT_LITTLETUMBLEWEED || mobj->type == MT_LITTLETUMBLEWEED
|| mobj->type == MT_CANNONBALLDECOR || mobj->type == MT_CANNONBALLDECOR
|| mobj->type == MT_FALLINGROCK) { || mobj->type == MT_FALLINGROCK
|| mobj->type == MT_ORBINAUT
|| mobj->type == MT_JAWZ || mobj->type == MT_JAWZ_DUD) {
P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly
//if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n");
P_ButteredSlope(mobj); P_ButteredSlope(mobj);
@ -10770,8 +11021,16 @@ void P_RespawnSpecials(void)
if (pcount == 1) // No respawn when alone if (pcount == 1) // No respawn when alone
return; return;
else if (pcount > 1) else if (pcount > 1)
{
time = (180 - (pcount * 10))*TICRATE; time = (180 - (pcount * 10))*TICRATE;
// If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this.
// 5 lap courses would have more retreaded ground, while 2 lap courses would have less.
if ((mapheaderinfo[gamemap-1]->numlaps != 3)
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE))
time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps);
}
// only respawn items when cv_itemrespawn is on // only respawn items when cv_itemrespawn is on
//if (!cv_itemrespawn.value) // TODO: remove this cvar //if (!cv_itemrespawn.value) // TODO: remove this cvar
//return; //return;
@ -11992,7 +12251,7 @@ ML_NOCLIMB : Direction not controllable
{ {
if (mthing->options & MTF_AMBUSH) if (mthing->options & MTF_AMBUSH)
{ {
if (i == MT_YELLOWDIAG || i == MT_REDDIAG) if (mobj->flags & MF_SPRING && mobj->info->damage)
mobj->angle += ANGLE_22h; mobj->angle += ANGLE_22h;
if (mobj->flags & MF_NIGHTSITEM) if (mobj->flags & MF_NIGHTSITEM)

View file

@ -370,6 +370,9 @@ typedef struct mobj_s
#ifdef ESLOPE #ifdef ESLOPE
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) 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 #endif
boolean colorized; // Whether the mobj uses the rainbow colormap boolean colorized; // Whether the mobj uses the rainbow colormap

View file

@ -2144,7 +2144,12 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
#ifdef ESLOPE #ifdef ESLOPE
if (diff2 & MD2_SLOPE) if (diff2 & MD2_SLOPE)
{
mobj->standingslope = P_SlopeById(READUINT16(save_p)); mobj->standingslope = P_SlopeById(READUINT16(save_p));
#ifdef HWRENDER
mobj->modeltilt = mobj->standingslope;
#endif
}
#endif #endif
if (diff2 & MD2_COLORIZED) if (diff2 & MD2_COLORIZED)
mobj->colorized = READUINT8(save_p); mobj->colorized = READUINT8(save_p);
@ -3091,7 +3096,7 @@ static inline void P_NetArchiveSpecials(void)
WRITEUINT32(save_p, 0xffffffff); WRITEUINT32(save_p, 0xffffffff);
// Sky number // Sky number
WRITEINT32(save_p, globallevelskynum); WRITESTRINGN(save_p, globallevelskytexture, 9);
// Current global weather type // Current global weather type
WRITEUINT8(save_p, globalweather); WRITEUINT8(save_p, globalweather);
@ -3110,8 +3115,8 @@ static inline void P_NetArchiveSpecials(void)
// //
static void P_NetUnArchiveSpecials(void) static void P_NetUnArchiveSpecials(void)
{ {
char skytex[9];
size_t i; size_t i;
INT32 j;
if (READUINT32(save_p) != ARCHIVEBLOCK_SPECIALS) if (READUINT32(save_p) != ARCHIVEBLOCK_SPECIALS)
I_Error("Bad $$$.sav at archive block Specials"); I_Error("Bad $$$.sav at archive block Specials");
@ -3124,9 +3129,9 @@ static void P_NetUnArchiveSpecials(void)
itemrespawntime[iquehead++] = READINT32(save_p); itemrespawntime[iquehead++] = READINT32(save_p);
} }
j = READINT32(save_p); READSTRINGN(save_p, skytex, sizeof(skytex));
if (j != globallevelskynum) if (strcmp(skytex, globallevelskytexture))
P_SetupLevelSky(j, true); P_SetupLevelSky(skytex, true);
globalweather = READUINT8(save_p); globalweather = READUINT8(save_p);

View file

@ -207,8 +207,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->forcecharacter[0] = '\0'; mapheaderinfo[num]->forcecharacter[0] = '\0';
DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE); DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE);
mapheaderinfo[num]->weather = 0; mapheaderinfo[num]->weather = 0;
DEH_WriteUndoline("SKYNUM", va("%d", mapheaderinfo[num]->skynum), UNDO_NONE); DEH_WriteUndoline("SKYTEXTURE", va("%d", mapheaderinfo[num]->skytexture), UNDO_NONE);
mapheaderinfo[num]->skynum = 1; snprintf(mapheaderinfo[num]->skytexture, 9, "SKY1");
mapheaderinfo[num]->skytexture[8] = 0;
DEH_WriteUndoline("SKYBOXSCALEX", va("%d", mapheaderinfo[num]->skybox_scalex), UNDO_NONE); DEH_WriteUndoline("SKYBOXSCALEX", va("%d", mapheaderinfo[num]->skybox_scalex), UNDO_NONE);
mapheaderinfo[num]->skybox_scalex = 16; mapheaderinfo[num]->skybox_scalex = 16;
DEH_WriteUndoline("SKYBOXSCALEY", va("%d", mapheaderinfo[num]->skybox_scaley), UNDO_NONE); DEH_WriteUndoline("SKYBOXSCALEY", va("%d", mapheaderinfo[num]->skybox_scaley), UNDO_NONE);
@ -2255,17 +2256,18 @@ static inline boolean P_CheckLevel(lumpnum_t lumpnum)
/** Sets up a sky texture to use for the level. /** Sets up a sky texture to use for the level.
* The sky texture is used instead of F_SKY1. * 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(tex);
skytexture = R_TextureNumForName(skytexname); strncpy(levelskytexture, tex, 9);
levelskynum = skynum;
// Global change // Global change
if (global) if (global)
globallevelskynum = levelskynum; strncpy(globallevelskytexture, tex, 9);
// Don't go beyond for dedicated servers // Don't go beyond for dedicated servers
if (dedicated) if (dedicated)
@ -2973,7 +2975,7 @@ boolean P_SetupLevel(boolean skipprecip)
CON_SetupBackColormap(); CON_SetupBackColormap();
// SRB2 determines the sky texture to be used depending on the map header. // 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); P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5);

View file

@ -54,7 +54,7 @@ INT32 P_CheckLevelFlat(const char *flatname);
extern size_t nummapthings; extern size_t nummapthings;
extern mapthing_t *mapthings; extern mapthing_t *mapthings;
void P_SetupLevelSky(INT32 skynum, boolean global); void P_SetupLevelSky(const char *skytexname, boolean global);
#ifdef SCANTHINGS #ifdef SCANTHINGS
void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
#endif #endif

View file

@ -625,8 +625,7 @@ void P_ResetDynamicSlopes(void) {
slopelist = NULL; slopelist = NULL;
slopecount = 0; slopecount = 0;
// We'll handle copy slopes later, after all the tag lists have been made. /// Generates line special-defined slopes.
// Yes, this means copied slopes won't affect things' spawning heights. Too bad for you.
for (i = 0; i < numlines; i++) for (i = 0; i < numlines; i++)
{ {
switch (lines[i].special) switch (lines[i].special)
@ -725,11 +724,21 @@ void P_ResetDynamicSlopes(void) {
break; break;
} }
} }
/// Copies slopes from tagged sectors via line specials.
/// \note Doesn't actually copy, but instead they share the same pointers.
for (i = 0; i < numlines; i++)
switch (lines[i].special)
{
case 720:
case 721:
case 722:
P_CopySectorSlope(&lines[i]);
default:
break;
}
} }
// ============================================================================ // ============================================================================
// //
// Various utilities related to slopes // Various utilities related to slopes
@ -827,6 +836,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope
thing->momz = -P_MobjFlip(thing); thing->momz = -P_MobjFlip(thing);
thing->standingslope = slope; thing->standingslope = slope;
#ifdef HWRENDER
thing->modeltilt = thing->standingslope;
#endif
} }
return; return;
} }
@ -843,6 +855,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
thing->momz = -P_MobjFlip(thing); thing->momz = -P_MobjFlip(thing);
thing->standingslope = slope; thing->standingslope = slope;
#ifdef HWRENDER
thing->modeltilt = thing->standingslope;
#endif
} }
} }
@ -862,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 return; // don't slide down slopes if you can't touch them or you're not affected by gravity
if (mo->player) { 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 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)) 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 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)) { if (mo->player) {
fixed_t mult = 0; fixed_t mult = FRACUNIT;
if (mo->momx || mo->momy) { if (mo->momx || mo->momy) {
angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection; angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection;
if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0) if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0)
angle ^= ANGLE_180; 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... // Let's get the gravity strength for the object...
thrust = FixedMul(thrust, abs(P_GetMobjGravity(mo))); thrust = FixedMul(thrust, abs(P_GetMobjGravity(mo)));

View file

@ -2802,7 +2802,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
case 423: // Change Sky case 423: // Change Sky
if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB)) 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; break;
case 424: // Change Weather case 424: // Change Weather
@ -6693,14 +6693,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
sectors[s].midmap = lines[i].frontsector->midmap; sectors[s].midmap = lines[i].frontsector->midmap;
break; break;
#ifdef ESLOPE // Slope copy specials. Handled here for sanity.
case 720:
case 721:
case 722:
P_CopySectorSlope(&lines[i]);
break;
#endif
default: default:
break; break;
} }

View file

@ -1645,12 +1645,16 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->frame |= tr_trans50<<FF_TRANSSHIFT; ghost->frame |= tr_trans50<<FF_TRANSSHIFT;
ghost->fuse = ghost->info->damage; ghost->fuse = ghost->info->damage;
ghost->skin = mobj->skin; ghost->skin = mobj->skin;
ghost->standingslope = mobj->standingslope;
#ifdef HWRENDER
ghost->modeltilt = mobj->modeltilt;
#endif
if (mobj->flags2 & MF2_OBJECTFLIP) if (mobj->flags2 & MF2_OBJECTFLIP)
ghost->flags |= MF2_OBJECTFLIP; ghost->flags |= MF2_OBJECTFLIP;
if (!(mobj->flags & MF_DONTENCOREMAP)) if (!(mobj->flags & MF_DONTENCOREMAP))
mobj->flags &= ~MF_DONTENCOREMAP; ghost->flags &= ~MF_DONTENCOREMAP;
return ghost; 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 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! // If "no" to 1, we're not reaching any limits yet, so ignore this entirely!
// -Shadow Hog // -Shadow Hog
newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); // Only do this forced cap of speed when in midair, the kart acceleration code takes into account friction, and
if (newMagnitude > K_GetKartSpeed(player, true)) //topspeed) // 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; newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
if (oldMagnitude > K_GetKartSpeed(player, true)) 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); if (newMagnitude > oldMagnitude)
tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, 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->momx = tempmomx + player->cmomx;
player->mo->momy = tempmomy + player->cmomy; 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;
} }
} }
} }

View file

@ -267,7 +267,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
texturememory += blocksize; texturememory += blocksize;
block = Z_Malloc(blocksize+1, PU_STATIC, &texturecache[texnum]); 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 // columns lookup table
colofs = (UINT32 *)(void *)block; colofs = (UINT32 *)(void *)block;
@ -1631,7 +1631,7 @@ void R_PrecacheLevel(void)
// Sky texture is always present. // Sky texture is always present.
// Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat, // 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; texturepresent[skytexture] = 1;
texturememory = 0; texturememory = 0;

View file

@ -734,7 +734,7 @@ void R_DrawPlanes(void)
dc_x = x; dc_x = x;
dc_source = dc_source =
R_GetColumn(texturetranslation[skytexture], R_GetColumn(texturetranslation[skytexture],
angle); -angle); // Negative because skies were being drawn horizontally flipped
wallcolfunc(); wallcolfunc();
} }
} }

View file

@ -47,8 +47,8 @@ fixed_t skyscale;
/** \brief used for keeping track of the current sky /** \brief used for keeping track of the current sky
*/ */
INT32 levelskynum; char levelskytexture[9];
INT32 globallevelskynum; char globallevelskytexture[9];
/** \brief The R_SetupSkyDraw function /** \brief The R_SetupSkyDraw function

View file

@ -30,8 +30,8 @@ extern INT32 skytexture, skytexturemid;
extern fixed_t skyscale; extern fixed_t skyscale;
extern INT32 skyflatnum; extern INT32 skyflatnum;
extern INT32 levelskynum; extern char levelskytexture[9];
extern INT32 globallevelskynum; extern char globallevelskytexture[9];
// call after skytexture is set to adapt for old/new skies // call after skytexture is set to adapt for old/new skies
void R_SetupSkyDraw(void); void R_SetupSkyDraw(void);

View file

@ -427,13 +427,13 @@ void SCR_DisplayTicRate(void)
ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));*/ ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));*/
// draw "FPS" // 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: // 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 "/" // 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 // 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; 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 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; 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);
} }
} }

View file

@ -1377,11 +1377,14 @@ void I_FinishUpdate(void)
if (I_SkipFrame()) if (I_SkipFrame())
return; return;
if (cv_ticrate.value) if (st_overlay)
SCR_DisplayTicRate(); {
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer) if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing(); SCR_DisplayLocalPing();
}
if (rendermode == render_soft && screens[0]) if (rendermode == render_soft && screens[0])
{ {