mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-11-15 17:21:34 +00:00
Merge branch 'master' into noclip-cam
This commit is contained in:
commit
738ee90d8a
32 changed files with 2330 additions and 441 deletions
|
@ -33,6 +33,7 @@
|
|||
#include "i_system.h"
|
||||
#include "d_main.h"
|
||||
#include "m_menu.h"
|
||||
#include "filesrch.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include "win32/win_main.h"
|
||||
|
@ -1303,12 +1304,15 @@ void CONS_Alert(alerttype_t level, const char *fmt, ...)
|
|||
switch (level)
|
||||
{
|
||||
case CONS_NOTICE:
|
||||
// no notice for notices, hehe
|
||||
CONS_Printf("\x83" "%s" "\x80 ", M_GetText("NOTICE:"));
|
||||
break;
|
||||
case CONS_WARNING:
|
||||
refreshdirmenu |= REFRESHDIR_WARNING;
|
||||
CONS_Printf("\x82" "%s" "\x80 ", M_GetText("WARNING:"));
|
||||
break;
|
||||
case CONS_ERROR:
|
||||
refreshdirmenu |= REFRESHDIR_ERROR;
|
||||
CONS_Printf("\x85" "%s" "\x80 ", M_GetText("ERROR:"));
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -343,6 +343,7 @@ typedef struct
|
|||
} ATTRPACK clientconfig_pak;
|
||||
|
||||
#define MAXSERVERNAME 32
|
||||
#define MAXFILENEEDED 915
|
||||
// This packet is too large
|
||||
typedef struct
|
||||
{
|
||||
|
@ -364,7 +365,7 @@ typedef struct
|
|||
unsigned char mapmd5[16];
|
||||
UINT8 actnum;
|
||||
UINT8 iszone;
|
||||
UINT8 fileneeded[915]; // is filled with writexxx (byteptr.h)
|
||||
UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
||||
} ATTRPACK serverinfo_pak;
|
||||
|
||||
typedef struct
|
||||
|
|
82
src/d_main.c
82
src/d_main.c
|
@ -74,6 +74,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
|||
#include "m_cond.h" // condition initialization
|
||||
#include "fastcmp.h"
|
||||
#include "keys.h"
|
||||
#include "filesrch.h" // refreshdirmenu, mainwadstally
|
||||
|
||||
#ifdef CMAKECONFIG
|
||||
#include "config.h"
|
||||
|
@ -681,6 +682,8 @@ void D_SRB2Loop(void)
|
|||
realtics = entertic - oldentertics;
|
||||
oldentertics = entertic;
|
||||
|
||||
refreshdirmenu = 0; // not sure where to put this, here as good as any?
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (!realtics)
|
||||
if (debugload)
|
||||
|
@ -954,43 +957,29 @@ static void IdentifyVersion(void)
|
|||
D_AddFile(va(pandf,srb2waddir,"patch.dta"));
|
||||
#endif
|
||||
|
||||
#define MUSICTEST(str) \
|
||||
{\
|
||||
const char *musicpath = va(pandf,srb2waddir,str);\
|
||||
int ms = W_VerifyNMUSlumps(musicpath); \
|
||||
if (ms == 1) \
|
||||
D_AddFile(musicpath); \
|
||||
else if (ms == 0) \
|
||||
I_Error("File "str" has been modified with non-music/sound lumps"); \
|
||||
}
|
||||
|
||||
// SRB2kart - Add graphics (temp) // The command for md5 checks is "W_VerifyFileMD5" - looks for ASSET_HASH_SRB2_SRB in config.h.in
|
||||
D_AddFile(va(pandf,srb2waddir,"gfx.kart"));
|
||||
D_AddFile(va(pandf,srb2waddir,"chars.kart"));
|
||||
D_AddFile(va(pandf,srb2waddir,"maps.kart"));
|
||||
D_AddFile(va(pandf,srb2waddir,"sounds.kart"));
|
||||
//D_AddFile(va(pandf,srb2waddir,"sounds.kart"));
|
||||
MUSICTEST("sounds.kart")
|
||||
|
||||
#ifdef USE_PATCH_KART
|
||||
D_AddFile(va(pandf,srb2waddir,"patch.kart"));
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
|
||||
{
|
||||
#if defined (DC) && 0
|
||||
const char *musicfile = "music_dc.dta";
|
||||
#else
|
||||
const char *musicfile = "music.dta";
|
||||
#endif
|
||||
const char *kmusicfile;
|
||||
const char *musicpath = va(pandf,srb2waddir,musicfile);
|
||||
const char *kmusicpath;
|
||||
int ms = W_VerifyNMUSlumps(musicpath); // Don't forget the music!
|
||||
int kms;
|
||||
if (ms == 1)
|
||||
D_AddFile(musicpath);
|
||||
else if (ms == 0)
|
||||
I_Error("File %s has been modified with non-music lumps",musicfile);
|
||||
|
||||
kmusicfile = "music.kart";
|
||||
kmusicpath = va(pandf,srb2waddir,kmusicfile);
|
||||
kms = W_VerifyNMUSlumps(kmusicpath); // kill me now
|
||||
|
||||
if (kms == 1)
|
||||
D_AddFile(kmusicpath);
|
||||
else if (kms == 0)
|
||||
I_Error("File %s has been modified with non-music lumps",kmusicfile);
|
||||
}
|
||||
#endif
|
||||
MUSICTEST("music.dta")
|
||||
MUSICTEST("music.kart")
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
|
@ -1250,26 +1239,43 @@ void D_SRB2Main(void)
|
|||
#endif
|
||||
D_CleanFile();
|
||||
|
||||
mainwads = 0;
|
||||
|
||||
#ifndef DEVELOP // md5s last updated 12/14/14
|
||||
|
||||
// Check MD5s of autoloaded files
|
||||
mainwads = 0;
|
||||
W_VerifyFileMD5(mainwads, ASSET_HASH_SRB2_SRB); mainwads++; // srb2.srb/srb2.wad
|
||||
W_VerifyFileMD5(mainwads, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
|
||||
#ifdef USE_PATCH_DTA
|
||||
W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_DTA); mainwads++; // patch.dta
|
||||
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_DTA); // patch.dta
|
||||
#endif
|
||||
W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_KART); mainwads++; // gfx.kart
|
||||
W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_KART); mainwads++; // chars.kart
|
||||
W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_KART); mainwads++; // maps.kart
|
||||
//W_VerifyFileMD5(mainwads, ASSET_HASH_SOUNDS_KART); mainwads++; // sounds.kart - doesn't trigger modifiedgame, doesn't need an MD5...?
|
||||
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_KART); // gfx.kart
|
||||
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_KART); // chars.kart
|
||||
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_KART); // maps.kart
|
||||
mainwads++; //W_VerifyFileMD5(5, ASSET_HASH_SOUNDS_KART); -- sounds.kart - doesn't trigger modifiedgame, doesn't need an MD5...?
|
||||
#ifdef USE_PATCH_KART
|
||||
W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_KART); mainwads++; // patch.kart
|
||||
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_KART); // patch.kart
|
||||
#endif
|
||||
|
||||
// don't check music.dta because people like to modify it, and it doesn't matter if they do
|
||||
mainwads++; // music.dta
|
||||
mainwads++; // music.kart
|
||||
// don't check music.dta or kart because people like to modify it, and it doesn't matter if they do
|
||||
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
|
||||
#else
|
||||
#ifdef USE_PATCH_DTA
|
||||
mainwads++; // patch.dta
|
||||
#endif
|
||||
mainwads++; // gfx.kart
|
||||
mainwads++; // chars.kart
|
||||
mainwads++; // maps.kart
|
||||
mainwads++; // sounds.kart
|
||||
#ifdef USE_PATCH_KART
|
||||
mainwads++; // patch.kart
|
||||
#endif
|
||||
mainwads++; // music.dta
|
||||
mainwads++; // music.kart
|
||||
#endif //ifndef DEVELOP
|
||||
|
||||
mainwadstally = packetsizetally;
|
||||
|
||||
cht_Init();
|
||||
|
||||
//---------------------------------------------------- READY SCREEN
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "d_main.h"
|
||||
#include "m_random.h"
|
||||
#include "f_finale.h"
|
||||
#include "filesrch.h"
|
||||
#include "mserv.h"
|
||||
#include "md5.h"
|
||||
#include "z_zone.h"
|
||||
|
@ -371,6 +372,7 @@ static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"},
|
|||
consvar_t cv_kartdebugamount = {"kartdebugamount", "1", CV_NETVAR|CV_CHEAT, kartdebugamount_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartdebugshrink = {"kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartdebugdistribution = {"kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
@ -831,6 +833,14 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_driftaxis3);
|
||||
CV_RegisterVar(&cv_driftaxis4);
|
||||
|
||||
// filesrch.c
|
||||
CV_RegisterVar(&cv_addons_option);
|
||||
CV_RegisterVar(&cv_addons_folder);
|
||||
CV_RegisterVar(&cv_addons_md5);
|
||||
CV_RegisterVar(&cv_addons_showall);
|
||||
CV_RegisterVar(&cv_addons_search_type);
|
||||
CV_RegisterVar(&cv_addons_search_case);
|
||||
|
||||
// WARNING: the order is important when initialising mouse2
|
||||
// we need the mouse2port
|
||||
CV_RegisterVar(&cv_mouse2port);
|
||||
|
@ -3758,25 +3768,12 @@ static void Command_Addfile(void)
|
|||
break;
|
||||
++p;
|
||||
// check total packet size and no of files currently loaded
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
if ((numwadfiles >= MAX_WADFILES)
|
||||
|| ((packetsizetally + nameonlylength(fn) + 22) > MAXFILENEEDED*sizeof(UINT8)))
|
||||
{
|
||||
size_t packetsize = 0;
|
||||
serverinfo_pak *dummycheck = NULL;
|
||||
|
||||
// Shut the compiler up.
|
||||
(void)dummycheck;
|
||||
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
||||
|
||||
packetsize += nameonlylength(fn) + 22;
|
||||
|
||||
if ((numwadfiles >= MAX_WADFILES)
|
||||
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn);
|
||||
return;
|
||||
}
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn);
|
||||
return;
|
||||
}
|
||||
|
||||
WRITESTRINGN(buf_p,p,240);
|
||||
|
@ -3862,11 +3859,6 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
|||
boolean kick = false;
|
||||
boolean toomany = false;
|
||||
INT32 i,j;
|
||||
size_t packetsize = 0;
|
||||
serverinfo_pak *dummycheck = NULL;
|
||||
|
||||
// Shut the compiler up.
|
||||
(void)dummycheck;
|
||||
|
||||
READSTRINGN(*cp, filename, 240);
|
||||
READMEM(*cp, md5sum, 16);
|
||||
|
@ -3893,13 +3885,8 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
||||
|
||||
packetsize += nameonlylength(filename) + 22;
|
||||
|
||||
if ((numwadfiles >= MAX_WADFILES)
|
||||
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
||||
|| ((packetsizetally + nameonlylength(filename) + 22) > MAXFILENEEDED*sizeof(UINT8)))
|
||||
toomany = true;
|
||||
else
|
||||
ncs = findfile(filename,md5sum,true);
|
||||
|
@ -4068,6 +4055,9 @@ static void Command_Playintro_f(void)
|
|||
if (netgame)
|
||||
return;
|
||||
|
||||
if (dirmenu)
|
||||
closefilemenu(true);
|
||||
|
||||
F_StartIntro();
|
||||
}
|
||||
|
||||
|
@ -4777,6 +4767,9 @@ void Command_ExitGame_f(void)
|
|||
cv_debug = 0;
|
||||
emeralds = 0;
|
||||
|
||||
if (dirmenu)
|
||||
closefilemenu(true);
|
||||
|
||||
if (!modeattacking)
|
||||
D_StartTitle();
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ extern consvar_t cv_karteliminatelast;
|
|||
|
||||
extern consvar_t cv_votetime;
|
||||
|
||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution;
|
||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||
extern consvar_t cv_kartdebugcheckpoint;
|
||||
|
||||
extern consvar_t cv_itemfinder;
|
||||
|
|
|
@ -104,6 +104,7 @@ INT32 lastfilenum = -1;
|
|||
/** Fills a serverinfo packet with information about wad files loaded.
|
||||
*
|
||||
* \todo Give this function a better name since it is in global scope.
|
||||
* Used to have size limiting built in - now handed via W_LoadWadFile in w_wad.c
|
||||
*
|
||||
*/
|
||||
UINT8 *PutFileNeeded(void)
|
||||
|
@ -112,29 +113,22 @@ UINT8 *PutFileNeeded(void)
|
|||
UINT8 *p = netbuffer->u.serverinfo.fileneeded;
|
||||
char wadfilename[MAX_WADPATH] = "";
|
||||
UINT8 filestatus;
|
||||
size_t bytesused = 0;
|
||||
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
{
|
||||
// If it has only music/sound lumps, mark it as unimportant
|
||||
if (W_VerifyNMUSlumps(wadfiles[i]->filename))
|
||||
filestatus = 0;
|
||||
else
|
||||
filestatus = 1; // Important
|
||||
// If it has only music/sound lumps, don't put it in the list
|
||||
if (!wadfiles[i]->important)
|
||||
continue;
|
||||
|
||||
filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS
|
||||
|
||||
// Store in the upper four bits
|
||||
if (!cv_downloading.value)
|
||||
filestatus += (2 << 4); // Won't send
|
||||
else if ((wadfiles[i]->filesize > (UINT32)cv_maxsend.value * 1024))
|
||||
filestatus += (0 << 4); // Won't send
|
||||
else
|
||||
else if ((wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024))
|
||||
filestatus += (1 << 4); // Will send if requested
|
||||
|
||||
bytesused += (nameonlylength(wadfilename) + 22);
|
||||
|
||||
// Don't write too far...
|
||||
if (bytesused > sizeof(netbuffer->u.serverinfo.fileneeded))
|
||||
I_Error("Too many wad files added to host a game. (%s, stopped on %s)\n", sizeu1(bytesused), wadfilename);
|
||||
// else
|
||||
// filestatus += (0 << 4); -- Won't send, too big
|
||||
|
||||
WRITEUINT8(p, filestatus);
|
||||
|
||||
|
@ -167,7 +161,6 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr)
|
|||
{
|
||||
fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet
|
||||
filestatus = READUINT8(p); // The first byte is the file status
|
||||
fileneeded[i].important = (UINT8)(filestatus & 3);
|
||||
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
||||
fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size
|
||||
fileneeded[i].file = NULL; // The file isn't open yet
|
||||
|
@ -197,7 +190,7 @@ boolean CL_CheckDownloadable(void)
|
|||
UINT8 i,dlstatus = 0;
|
||||
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && fileneeded[i].important)
|
||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||
{
|
||||
if (fileneeded[i].willsend == 1)
|
||||
continue;
|
||||
|
@ -218,7 +211,7 @@ boolean CL_CheckDownloadable(void)
|
|||
// not downloadable, put reason in console
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && fileneeded[i].important)
|
||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||
{
|
||||
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
|
||||
|
||||
|
@ -271,7 +264,7 @@ boolean CL_SendRequestFile(void)
|
|||
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN
|
||||
&& fileneeded[i].important && (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
||||
&& (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
||||
{
|
||||
I_Error("Attempted to download files that were not sendable");
|
||||
}
|
||||
|
@ -280,8 +273,7 @@ boolean CL_SendRequestFile(void)
|
|||
netbuffer->packettype = PT_REQUESTFILE;
|
||||
p = (char *)netbuffer->u.textcmd;
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)
|
||||
&& fileneeded[i].important)
|
||||
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD))
|
||||
{
|
||||
totalfreespaceneeded += fileneeded[i].totalsize;
|
||||
nameonly(fileneeded[i].filename);
|
||||
|
@ -339,10 +331,6 @@ INT32 CL_CheckFiles(void)
|
|||
INT32 ret = 1;
|
||||
size_t packetsize = 0;
|
||||
size_t filestoget = 0;
|
||||
serverinfo_pak *dummycheck = NULL;
|
||||
|
||||
// Shut the compiler up.
|
||||
(void)dummycheck;
|
||||
|
||||
// if (M_CheckParm("-nofiles"))
|
||||
// return 1;
|
||||
|
@ -360,13 +348,7 @@ INT32 CL_CheckFiles(void)
|
|||
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
||||
for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;)
|
||||
{
|
||||
if (i < fileneedednum && !fileneeded[i].important)
|
||||
{
|
||||
// Eh whatever, don't care
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (j < numwadfiles && W_VerifyNMUSlumps(wadfiles[j]->filename))
|
||||
if (j < numwadfiles && !wadfiles[j]->important)
|
||||
{
|
||||
// Unimportant on our side. still don't care.
|
||||
++j;
|
||||
|
@ -392,8 +374,7 @@ INT32 CL_CheckFiles(void)
|
|||
}
|
||||
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
||||
packetsize = packetsizetally;
|
||||
|
||||
for (i = 1; i < fileneedednum; i++)
|
||||
{
|
||||
|
@ -411,13 +392,13 @@ INT32 CL_CheckFiles(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (fileneeded[i].status != FS_NOTFOUND || !fileneeded[i].important)
|
||||
if (fileneeded[i].status != FS_NOTFOUND)
|
||||
continue;
|
||||
|
||||
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
||||
|
||||
if ((numwadfiles+filestoget >= MAX_WADFILES)
|
||||
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
||||
|| (packetsize > MAXFILENEEDED*sizeof(UINT8)))
|
||||
return 3;
|
||||
|
||||
filestoget++;
|
||||
|
@ -449,27 +430,8 @@ void CL_LoadServerFiles(void)
|
|||
fileneeded[i].status = FS_OPEN;
|
||||
}
|
||||
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
||||
{
|
||||
// If the file is marked important, don't even bother proceeding.
|
||||
if (fileneeded[i].important)
|
||||
I_Error("Wrong version of important file %s", fileneeded[i].filename);
|
||||
|
||||
// If it isn't, no need to worry the user with a console message,
|
||||
// although it can't hurt to put something in the debug file.
|
||||
|
||||
// ...but wait a second. What if the local version is "important"?
|
||||
if (!W_VerifyNMUSlumps(fileneeded[i].filename))
|
||||
I_Error("File %s should only contain music and sound effects!",
|
||||
fileneeded[i].filename);
|
||||
|
||||
// Okay, NOW we know it's safe. Whew.
|
||||
P_AddWadFile(fileneeded[i].filename, NULL);
|
||||
if (fileneeded[i].important)
|
||||
G_SetGameModified(true);
|
||||
fileneeded[i].status = FS_OPEN;
|
||||
DEBFILE(va("File %s found but with different md5sum\n", fileneeded[i].filename));
|
||||
}
|
||||
else if (fileneeded[i].important)
|
||||
I_Error("Wrong version of file %s", fileneeded[i].filename);
|
||||
else
|
||||
{
|
||||
const char *s;
|
||||
switch(fileneeded[i].status)
|
||||
|
@ -939,10 +901,11 @@ void nameonly(char *s)
|
|||
{
|
||||
ns = &(s[j+1]);
|
||||
len = strlen(ns);
|
||||
if (false)
|
||||
#if 0
|
||||
M_Memcpy(s, ns, len+1);
|
||||
else
|
||||
#else
|
||||
memmove(s, ns, len+1);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ typedef enum
|
|||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 important;
|
||||
UINT8 willsend; // Is the server willing to send it?
|
||||
char filename[MAX_WADPATH];
|
||||
UINT8 md5sum[16];
|
||||
|
|
|
@ -305,6 +305,7 @@ typedef enum
|
|||
k_accelboost, // Boost value smoothing for acceleration
|
||||
k_boostcam, // Camera push forward on boost
|
||||
k_destboostcam, // Ditto
|
||||
k_aizdriftstrat, // Let go of your drift while boosting? Helper for the SICK STRATZ you have just unlocked
|
||||
|
||||
k_itemroulette, // Used for the roulette when deciding what item to give you (was "pw_kartitem")
|
||||
k_roulettetype, // Used for the roulette, for deciding type (currently only used for Battle, to give you better items from Karma items)
|
||||
|
|
|
@ -1830,6 +1830,7 @@ static actionpointer_t actionpointers[] =
|
|||
{{A_JawzExplode}, "A_JAWZEXPLODE"}, // SRB2kart
|
||||
{{A_MineExplode}, "A_MINEEXPLODE"}, // SRB2kart
|
||||
{{A_BallhogExplode}, "A_BALLHOGEXPLODE"}, // SRB2kart
|
||||
{{A_LightningFollowPlayer}, "A_LIGHTNINGFOLLOWPLAYER"}, //SRB2kart
|
||||
{{A_OrbitNights}, "A_ORBITNIGHTS"},
|
||||
{{A_GhostMe}, "A_GHOSTME"},
|
||||
{{A_SetObjectState}, "A_SETOBJECTSTATE"},
|
||||
|
@ -6205,6 +6206,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_RANDOMITEMPOP4",
|
||||
//}
|
||||
|
||||
"S_ITEMICON",
|
||||
|
||||
// Signpost sparkles
|
||||
"S_SIGNSPARK1",
|
||||
"S_SIGNSPARK2",
|
||||
|
@ -6270,6 +6273,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_KARTFIRE7",
|
||||
"S_KARTFIRE8",
|
||||
|
||||
// Angel Island Drift Strat Dust (what a mouthful!)
|
||||
"S_KARTAIZDRIFTSTRAT",
|
||||
|
||||
// Invincibility Sparks
|
||||
"S_KARTINVULN_SMALL1",
|
||||
"S_KARTINVULN_SMALL2",
|
||||
|
@ -6518,16 +6524,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
// Audience Members
|
||||
"S_RANDOMAUDIENCE",
|
||||
"S_AUDIENCE_TOAD1",
|
||||
"S_AUDIENCE_TOAD2",
|
||||
"S_AUDIENCE_BOO1",
|
||||
"S_AUDIENCE_BOO2",
|
||||
"S_AUDIENCE_GMBA1",
|
||||
"S_AUDIENCE_GMBA2",
|
||||
"S_AUDIENCE_SHYG1",
|
||||
"S_AUDIENCE_SHYG2",
|
||||
"S_AUDIENCE_SNIF1",
|
||||
"S_AUDIENCE_SNIF2",
|
||||
"S_AUDIENCE_CHAO_CHEER1",
|
||||
"S_AUDIENCE_CHAO_CHEER2",
|
||||
"S_AUDIENCE_CHAO_WIN1",
|
||||
"S_AUDIENCE_CHAO_WIN2",
|
||||
"S_AUDIENCE_CHAO_LOSE",
|
||||
|
||||
"S_FANCHAR_KOTE",
|
||||
"S_FANCHAR_RYAN",
|
||||
|
@ -6703,6 +6704,54 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
"S_KARMAWHEEL", // Karma player wheels
|
||||
|
||||
// Thunder shield use stuff;
|
||||
"S_KSPARK1", // Sparkling Radius
|
||||
"S_KSPARK2",
|
||||
"S_KSPARK3",
|
||||
"S_KSPARK4",
|
||||
"S_KSPARK5",
|
||||
"S_KSPARK6",
|
||||
"S_KSPARK7",
|
||||
"S_KSPARK8",
|
||||
"S_KSPARK9",
|
||||
"S_KSPARK10",
|
||||
"S_KSPARK11",
|
||||
"S_KSPARK12",
|
||||
"S_KSPARK13", // ... that's an awful lot.
|
||||
|
||||
"S_LZIO11", // Straight lightning bolt
|
||||
"S_LZIO12",
|
||||
"S_LZIO13",
|
||||
"S_LZIO14",
|
||||
"S_LZIO15",
|
||||
"S_LZIO16",
|
||||
"S_LZIO17",
|
||||
"S_LZIO18",
|
||||
"S_LZIO19",
|
||||
|
||||
"S_LZIO21", // Straight lightning bolt (flipped)
|
||||
"S_LZIO22",
|
||||
"S_LZIO23",
|
||||
"S_LZIO24",
|
||||
"S_LZIO25",
|
||||
"S_LZIO26",
|
||||
"S_LZIO27",
|
||||
"S_LZIO28",
|
||||
"S_LZIO29",
|
||||
|
||||
"S_KLIT1", // Diagonal lightning. No, it not being straight doesn't make it gay.
|
||||
"S_KLIT2",
|
||||
"S_KLIT3",
|
||||
"S_KLIT4",
|
||||
"S_KLIT5",
|
||||
"S_KLIT6",
|
||||
"S_KLIT7",
|
||||
"S_KLIT8",
|
||||
"S_KLIT9",
|
||||
"S_KLIT10",
|
||||
"S_KLIT11",
|
||||
"S_KLIT12",
|
||||
|
||||
#ifdef SEENAMES
|
||||
"S_NAMECHECK",
|
||||
#endif
|
||||
|
@ -7219,6 +7268,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_BLUEDIAG",
|
||||
"MT_RANDOMITEM",
|
||||
"MT_RANDOMITEMPOP",
|
||||
"MT_FLOATINGITEM",
|
||||
|
||||
"MT_SIGNSPARKLE",
|
||||
|
||||
"MT_FASTLINE",
|
||||
|
@ -7226,6 +7277,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_BOOSTFLAME",
|
||||
"MT_BOOSTSMOKE",
|
||||
"MT_SNEAKERTRAIL",
|
||||
"MT_AIZDRIFTSTRAT",
|
||||
"MT_SPARKLETRAIL",
|
||||
"MT_INVULNFLASH",
|
||||
"MT_WIPEOUTTRAIL",
|
||||
|
@ -7706,6 +7758,7 @@ static const char *const KARTSTUFF_LIST[] = {
|
|||
"ACCELBOOST",
|
||||
"BOOSTCAM",
|
||||
"DESTBOOSTCAM",
|
||||
"AIZDRIFTSTRAT",
|
||||
|
||||
"ITEMROULETTE",
|
||||
"ROULETTETYPE",
|
||||
|
|
473
src/filesrch.c
473
src/filesrch.c
|
@ -31,6 +31,8 @@
|
|||
#include "filesrch.h"
|
||||
#include "d_netfil.h"
|
||||
#include "m_misc.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_menu.h" // Addons_option_Onchange
|
||||
|
||||
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
|
||||
|
||||
|
@ -255,6 +257,28 @@ readdir (DIR * dirp)
|
|||
return (struct dirent *) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* rewinddir
|
||||
*
|
||||
* Makes the next readdir start from the beginning.
|
||||
*/
|
||||
int
|
||||
rewinddir (DIR * dirp)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
/* Check for valid DIR struct. */
|
||||
if (!dirp)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dirp->dd_stat = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* closedir
|
||||
*
|
||||
|
@ -285,6 +309,41 @@ closedir (DIR * dirp)
|
|||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static CV_PossibleValue_t addons_cons_t[] = {{0, "Default"},
|
||||
#if 1
|
||||
{1, "HOME"}, {2, "SRB2"},
|
||||
#endif
|
||||
{3, "CUSTOM"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_addons_option = {"addons_option", "Default", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_addons_folder = {"addons_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t addons_md5_cons_t[] = {{0, "Name"}, {1, "Contents"}, {0, NULL}};
|
||||
consvar_t cv_addons_md5 = {"addons_md5", "Name", CV_SAVE, addons_md5_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_addons_showall = {"addons_showall", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_addons_search_case = {"addons_search_case", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t addons_search_type_cons_t[] = {{0, "Start"}, {1, "Anywhere"}, {0, NULL}};
|
||||
consvar_t cv_addons_search_type = {"addons_search_type", "Anywhere", CV_SAVE, addons_search_type_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
char menupath[1024];
|
||||
size_t menupathindex[menudepth];
|
||||
size_t menudepthleft = menudepth;
|
||||
|
||||
char menusearch[MAXSTRINGLENGTH+1];
|
||||
|
||||
char **dirmenu, **coredirmenu; // core only local for this file
|
||||
size_t sizedirmenu, sizecoredirmenu; // ditto
|
||||
size_t dir_on[menudepth];
|
||||
UINT8 refreshdirmenu = 0;
|
||||
char *refreshdirname = NULL;
|
||||
|
||||
size_t packetsizetally = 0;
|
||||
size_t mainwadstally = 0;
|
||||
|
||||
#if defined (_XBOX) && defined (_MSC_VER)
|
||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||
boolean completepath, int maxsearchdepth)
|
||||
|
@ -296,6 +355,25 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
|||
completepath = false;
|
||||
return FS_NOTFOUND;
|
||||
}
|
||||
|
||||
void closefilemenu(boolean validsize)
|
||||
{
|
||||
(void)validsize;
|
||||
return;
|
||||
}
|
||||
|
||||
void searchfilemenu(char *tempname)
|
||||
{
|
||||
(void)tempname;
|
||||
return;
|
||||
}
|
||||
|
||||
boolean preparefilemenu(boolean samedepth)
|
||||
{
|
||||
(void)samedepth;
|
||||
return false;
|
||||
}
|
||||
|
||||
#elif defined (_WIN32_WCE)
|
||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||
boolean completepath, int maxsearchdepth)
|
||||
|
@ -346,7 +424,27 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
|||
#endif
|
||||
return FS_NOTFOUND;
|
||||
}
|
||||
|
||||
void closefilemenu(boolean validsize)
|
||||
{
|
||||
(void)validsize;
|
||||
return;
|
||||
}
|
||||
|
||||
void searchfilemenu(char *tempname)
|
||||
{
|
||||
(void)tempname;
|
||||
return;
|
||||
}
|
||||
|
||||
boolean preparefilemenu(boolean samedepth)
|
||||
{
|
||||
(void)samedepth;
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
|
||||
{
|
||||
filestatus_t retval = FS_NOTFOUND;
|
||||
|
@ -387,25 +485,29 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
|||
{
|
||||
searchpath[searchpathindex[depthleft]]=0;
|
||||
dent = readdir(dirhandle[depthleft]);
|
||||
if (dent)
|
||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
||||
|
||||
if (!dent)
|
||||
{
|
||||
closedir(dirhandle[depthleft++]);
|
||||
else if (dent->d_name[0]=='.' &&
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dent->d_name[0]=='.' &&
|
||||
(dent->d_name[1]=='\0' ||
|
||||
(dent->d_name[1]=='.' &&
|
||||
dent->d_name[2]=='\0')))
|
||||
{
|
||||
// we don't want to scan uptree
|
||||
continue;
|
||||
}
|
||||
else if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||
{
|
||||
// was the file (re)moved? can't stat it
|
||||
}
|
||||
|
||||
// okay, now we actually want searchpath to incorporate d_name
|
||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
||||
|
||||
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||
; // was the file (re)moved? can't stat it
|
||||
else if (S_ISDIR(fsstat.st_mode) && depthleft)
|
||||
{
|
||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
||||
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
||||
dirhandle[depthleft] = opendir(searchpath);
|
||||
if (!dirhandle[depthleft])
|
||||
|
@ -444,6 +546,361 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
|||
free(searchname);
|
||||
free(searchpathindex);
|
||||
free(dirhandle);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
char exttable[NUM_EXT_TABLE][7] = { // maximum extension length (currently 4) plus 3 (null terminator, stop, and length including previous two)
|
||||
"\5.txt", "\5.cfg", // exec
|
||||
"\5.wad", "\6.kart", /*"\5.pk3",*/ "\5.soc", "\5.lua"}; // addfile
|
||||
|
||||
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
||||
|
||||
|
||||
static boolean filemenucmp(char *haystack, char *needle)
|
||||
{
|
||||
static char localhaystack[128];
|
||||
strlcpy(localhaystack, haystack, 128);
|
||||
if (!cv_addons_search_case.value)
|
||||
strupr(localhaystack);
|
||||
if (cv_addons_search_type.value)
|
||||
return (strstr(localhaystack, needle) != 0);
|
||||
return (!strncmp(localhaystack, needle, menusearch[0]));
|
||||
}
|
||||
|
||||
void closefilemenu(boolean validsize)
|
||||
{
|
||||
// search
|
||||
if (dirmenu)
|
||||
{
|
||||
if (dirmenu != coredirmenu)
|
||||
{
|
||||
if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS))
|
||||
{
|
||||
Z_Free(dirmenu[0]);
|
||||
dirmenu[0] = NULL;
|
||||
}
|
||||
Z_Free(dirmenu);
|
||||
}
|
||||
dirmenu = NULL;
|
||||
sizedirmenu = 0;
|
||||
}
|
||||
|
||||
if (coredirmenu)
|
||||
{
|
||||
// core
|
||||
if (validsize)
|
||||
{
|
||||
for (; sizecoredirmenu > 0; sizecoredirmenu--)
|
||||
{
|
||||
Z_Free(coredirmenu[sizecoredirmenu-1]);
|
||||
coredirmenu[sizecoredirmenu-1] = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
sizecoredirmenu = 0;
|
||||
|
||||
Z_Free(coredirmenu);
|
||||
coredirmenu = NULL;
|
||||
}
|
||||
|
||||
if (refreshdirname)
|
||||
Z_Free(refreshdirname);
|
||||
refreshdirname = NULL;
|
||||
}
|
||||
|
||||
void searchfilemenu(char *tempname)
|
||||
{
|
||||
size_t i, first;
|
||||
char localmenusearch[MAXSTRINGLENGTH] = "";
|
||||
|
||||
if (dirmenu)
|
||||
{
|
||||
if (dirmenu != coredirmenu)
|
||||
{
|
||||
if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS))
|
||||
{
|
||||
Z_Free(dirmenu[0]);
|
||||
dirmenu[0] = NULL;
|
||||
}
|
||||
//Z_Free(dirmenu); -- Z_Realloc later tho...
|
||||
}
|
||||
else
|
||||
dirmenu = NULL;
|
||||
}
|
||||
|
||||
first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP...
|
||||
|
||||
if (!menusearch[0])
|
||||
{
|
||||
if (dirmenu)
|
||||
Z_Free(dirmenu);
|
||||
dirmenu = coredirmenu;
|
||||
sizedirmenu = sizecoredirmenu;
|
||||
|
||||
if (tempname)
|
||||
{
|
||||
for (i = first; i < sizedirmenu; i++)
|
||||
{
|
||||
if (!strcmp(dirmenu[i]+DIR_STRING, tempname))
|
||||
{
|
||||
dir_on[menudepthleft] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == sizedirmenu)
|
||||
dir_on[menudepthleft] = first;
|
||||
|
||||
Z_Free(tempname);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(localmenusearch, menusearch+1);
|
||||
if (!cv_addons_search_case.value)
|
||||
strupr(localmenusearch);
|
||||
|
||||
sizedirmenu = 0;
|
||||
for (i = first; i < sizecoredirmenu; i++)
|
||||
{
|
||||
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
|
||||
sizedirmenu++;
|
||||
}
|
||||
|
||||
if (!sizedirmenu) // no results...
|
||||
{
|
||||
if ((!(dirmenu = Z_Realloc(dirmenu, sizeof(char *), PU_STATIC, NULL)))
|
||||
|| !(dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS))))
|
||||
I_Error("searchfilemenu(): could not create \"No results...\".");
|
||||
sizedirmenu = 1;
|
||||
dir_on[menudepthleft] = 0;
|
||||
if (tempname)
|
||||
Z_Free(tempname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL)))
|
||||
I_Error("searchfilemenu(): could not reallocate dirmenu.");
|
||||
|
||||
sizedirmenu = 0;
|
||||
for (i = first; i < sizecoredirmenu; i++)
|
||||
{
|
||||
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
|
||||
{
|
||||
if (tempname && !strcmp(coredirmenu[i]+DIR_STRING, tempname))
|
||||
{
|
||||
dir_on[menudepthleft] = sizedirmenu;
|
||||
Z_Free(tempname);
|
||||
tempname = NULL;
|
||||
}
|
||||
dirmenu[sizedirmenu++] = coredirmenu[i]; // pointer reuse
|
||||
}
|
||||
}
|
||||
|
||||
if (tempname)
|
||||
{
|
||||
dir_on[menudepthleft] = 0; //first; -- can't be first, causes problems
|
||||
Z_Free(tempname);
|
||||
}
|
||||
}
|
||||
|
||||
boolean preparefilemenu(boolean samedepth)
|
||||
{
|
||||
DIR *dirhandle;
|
||||
struct dirent *dent;
|
||||
struct stat fsstat;
|
||||
size_t pos = 0, folderpos = 0, numfolders = 0;
|
||||
char *tempname = NULL;
|
||||
|
||||
if (samedepth)
|
||||
{
|
||||
if (dirmenu && dirmenu[dir_on[menudepthleft]])
|
||||
tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL
|
||||
}
|
||||
else
|
||||
menusearch[0] = menusearch[1] = 0; // clear search
|
||||
|
||||
if (!(dirhandle = opendir(menupath))) // get directory
|
||||
{
|
||||
closefilemenu(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (; sizecoredirmenu > 0; sizecoredirmenu--) // clear out existing items
|
||||
{
|
||||
Z_Free(coredirmenu[sizecoredirmenu-1]);
|
||||
coredirmenu[sizecoredirmenu-1] = NULL;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
menupath[menupathindex[menudepthleft]] = 0;
|
||||
dent = readdir(dirhandle);
|
||||
|
||||
if (!dent)
|
||||
break;
|
||||
else if (dent->d_name[0]=='.' &&
|
||||
(dent->d_name[1]=='\0' ||
|
||||
(dent->d_name[1]=='.' &&
|
||||
dent->d_name[2]=='\0')))
|
||||
continue; // we don't want to scan uptree
|
||||
|
||||
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
|
||||
|
||||
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||
; // was the file (re)moved? can't stat it
|
||||
else // is a file or directory
|
||||
{
|
||||
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||
{
|
||||
if (!cv_addons_showall.value)
|
||||
{
|
||||
size_t len = strlen(dent->d_name)+1;
|
||||
UINT8 ext;
|
||||
for (ext = 0; ext < NUM_EXT_TABLE; ext++)
|
||||
if (!strcasecmp(exttable[ext]+1, dent->d_name+len-(exttable[ext][0]))) break; // extension comparison
|
||||
if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file
|
||||
}
|
||||
}
|
||||
else // directory
|
||||
numfolders++;
|
||||
|
||||
sizecoredirmenu++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sizecoredirmenu)
|
||||
{
|
||||
closedir(dirhandle);
|
||||
closefilemenu(false);
|
||||
if (tempname)
|
||||
Z_Free(tempname);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (menudepthleft != menudepth-1) // Make room for UP...
|
||||
{
|
||||
sizecoredirmenu++;
|
||||
numfolders++;
|
||||
folderpos++;
|
||||
}
|
||||
|
||||
if (dirmenu && dirmenu == coredirmenu)
|
||||
dirmenu = NULL;
|
||||
|
||||
if (!(coredirmenu = Z_Realloc(coredirmenu, sizecoredirmenu*sizeof(char *), PU_STATIC, NULL)))
|
||||
{
|
||||
closedir(dirhandle); // just in case
|
||||
I_Error("preparefilemenu(): could not reallocate coredirmenu.");
|
||||
}
|
||||
|
||||
rewinddir(dirhandle);
|
||||
|
||||
while ((pos+folderpos) < sizecoredirmenu)
|
||||
{
|
||||
menupath[menupathindex[menudepthleft]] = 0;
|
||||
dent = readdir(dirhandle);
|
||||
|
||||
if (!dent)
|
||||
break;
|
||||
else if (dent->d_name[0]=='.' &&
|
||||
(dent->d_name[1]=='\0' ||
|
||||
(dent->d_name[1]=='.' &&
|
||||
dent->d_name[2]=='\0')))
|
||||
continue; // we don't want to scan uptree
|
||||
|
||||
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
|
||||
|
||||
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||
; // was the file (re)moved? can't stat it
|
||||
else // is a file or directory
|
||||
{
|
||||
char *temp;
|
||||
size_t len = strlen(dent->d_name)+1;
|
||||
UINT8 ext = EXT_FOLDER;
|
||||
UINT8 folder;
|
||||
|
||||
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||
{
|
||||
if (!((numfolders+pos) < sizecoredirmenu)) continue; // crash prevention
|
||||
for (; ext < NUM_EXT_TABLE; ext++)
|
||||
if (!strcasecmp(exttable[ext]+1, dent->d_name+len-(exttable[ext][0]))) break; // extension comparison
|
||||
if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file
|
||||
ext += EXT_START; // moving to be appropriate position
|
||||
|
||||
if (ext >= EXT_LOADSTART)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
{
|
||||
if (!filenamebuf[i][0])
|
||||
{
|
||||
strncpy(filenamebuf[i], wadfiles[i]->filename, MAX_WADPATH);
|
||||
filenamebuf[i][MAX_WADPATH - 1] = '\0';
|
||||
nameonly(filenamebuf[i]);
|
||||
}
|
||||
|
||||
if (strcmp(dent->d_name, filenamebuf[i]))
|
||||
continue;
|
||||
if (cv_addons_md5.value && !checkfilemd5(menupath, wadfiles[i]->md5sum))
|
||||
continue;
|
||||
|
||||
ext |= EXT_LOADED;
|
||||
}
|
||||
}
|
||||
else if (ext == EXT_TXT)
|
||||
{
|
||||
if (!strcmp(dent->d_name, "log.txt") || !strcmp(dent->d_name, "errorlog.txt"))
|
||||
ext |= EXT_LOADED;
|
||||
}
|
||||
|
||||
if (!strcmp(dent->d_name, configfile))
|
||||
ext |= EXT_LOADED;
|
||||
|
||||
folder = 0;
|
||||
}
|
||||
else // directory
|
||||
len += (folder = 1);
|
||||
|
||||
if (len > 255)
|
||||
len = 255;
|
||||
|
||||
if (!(temp = Z_Malloc((len+DIR_STRING+folder) * sizeof (char), PU_STATIC, NULL)))
|
||||
I_Error("preparefilemenu(): could not create file entry.");
|
||||
temp[DIR_TYPE] = ext;
|
||||
temp[DIR_LEN] = (UINT8)(len);
|
||||
strlcpy(temp+DIR_STRING, dent->d_name, len);
|
||||
if (folder)
|
||||
{
|
||||
strcpy(temp+len, PATHSEP);
|
||||
coredirmenu[folderpos++] = temp;
|
||||
}
|
||||
else
|
||||
coredirmenu[numfolders + pos++] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dirhandle);
|
||||
|
||||
if ((menudepthleft != menudepth-1) // now for UP... entry
|
||||
&& !(coredirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP))))
|
||||
I_Error("preparefilemenu(): could not create \"UP...\".");
|
||||
|
||||
menupath[menupathindex[menudepthleft]] = 0;
|
||||
sizecoredirmenu = (numfolders+pos); // just in case things shrink between opening and rewind
|
||||
|
||||
if (!sizecoredirmenu)
|
||||
{
|
||||
dir_on[menudepthleft] = 0;
|
||||
closefilemenu(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
searchfilemenu(tempname);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "d_netfil.h"
|
||||
#include "m_menu.h" // MAXSTRINGLENGTH
|
||||
|
||||
extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_showall, cv_addons_search_case, cv_addons_search_type;
|
||||
|
||||
/** \brief The filesearch function
|
||||
|
||||
|
@ -25,4 +28,69 @@
|
|||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||
boolean completepath, int maxsearchdepth);
|
||||
|
||||
#define menudepth 20
|
||||
|
||||
extern char menupath[1024];
|
||||
extern size_t menupathindex[menudepth];
|
||||
extern size_t menudepthleft;
|
||||
|
||||
extern char menusearch[MAXSTRINGLENGTH+1];
|
||||
|
||||
extern char **dirmenu;
|
||||
extern size_t sizedirmenu;
|
||||
extern size_t dir_on[menudepth];
|
||||
extern UINT8 refreshdirmenu;
|
||||
extern char *refreshdirname;
|
||||
|
||||
extern size_t packetsizetally;
|
||||
extern size_t mainwadstally;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EXT_FOLDER = 0,
|
||||
EXT_UP,
|
||||
EXT_NORESULTS,
|
||||
EXT_START,
|
||||
EXT_TXT = EXT_START,
|
||||
EXT_CFG,
|
||||
EXT_LOADSTART,
|
||||
EXT_WAD = EXT_LOADSTART,
|
||||
EXT_KART,
|
||||
//EXT_PK3,
|
||||
EXT_SOC,
|
||||
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt
|
||||
NUM_EXT,
|
||||
NUM_EXT_TABLE = NUM_EXT-EXT_START,
|
||||
EXT_LOADED = 0x80
|
||||
/*
|
||||
obviously there can only be 0x7F supported extensions in
|
||||
addons menu because we're cramming this into a char out of
|
||||
laziness/easy memory allocation (what's the difference?)
|
||||
and have stolen a bit to show whether it's loaded or not
|
||||
in practice the size of the data type is probably overkill
|
||||
toast 02/05/17
|
||||
*/
|
||||
} ext_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DIR_TYPE = 0,
|
||||
DIR_LEN,
|
||||
DIR_STRING
|
||||
} dirname_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
REFRESHDIR_NORMAL = 1,
|
||||
REFRESHDIR_ADDFILE = 2,
|
||||
REFRESHDIR_WARNING = 4,
|
||||
REFRESHDIR_ERROR = 8,
|
||||
REFRESHDIR_NOTLOADED = 16,
|
||||
REFRESHDIR_MAX = 32
|
||||
} refreshdir_enum;
|
||||
|
||||
void closefilemenu(boolean validsize);
|
||||
void searchfilemenu(char *tempname);
|
||||
boolean preparefilemenu(boolean samedepth);
|
||||
|
||||
#endif // __FILESRCH_H__
|
||||
|
|
202
src/info.c
202
src/info.c
|
@ -60,7 +60,8 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"KRBM","BHOG","BHBM","BLIG","LIGH","THNS","SINK","SITR","KBLN","DEZL",
|
||||
"POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM","SACO",
|
||||
"CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB","ARRO",
|
||||
"ITEM","ITMO","ITMI","ITMN","WANT","PBOM","RETI","VIEW"
|
||||
"ITEM","ITMO","ITMI","ITMN","WANT","PBOM","RETI","AIDU","KSPK","LZI1",
|
||||
"LZI2","KLIT","VIEW"
|
||||
};
|
||||
|
||||
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)
|
||||
|
@ -1725,11 +1726,11 @@ state_t states[NUMSTATES] =
|
|||
{SPR_IVSP, FF_ANIMATE, 32, {NULL}, 31, 1, S_NULL}, // S_IVSP
|
||||
|
||||
// Super Sonic Spark
|
||||
{SPR_SSPK, 0, 2, {NULL}, 0, 0, S_SSPK2}, // S_SSPK1
|
||||
{SPR_SSPK, 1, 2, {NULL}, 0, 0, S_SSPK3}, // S_SSPK2
|
||||
{SPR_SSPK, 2, 2, {NULL}, 0, 0, S_SSPK4}, // S_SSPK3
|
||||
{SPR_SSPK, 1, 2, {NULL}, 0, 0, S_SSPK5}, // S_SSPK4
|
||||
{SPR_SSPK, 0, 2, {NULL}, 0, 0, S_NULL}, // S_SSPK5
|
||||
{SPR_SSPK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK2}, // S_SSPK1
|
||||
{SPR_SSPK, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK3}, // S_SSPK2
|
||||
{SPR_SSPK, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK4}, // S_SSPK3
|
||||
{SPR_SSPK, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK5}, // S_SSPK4
|
||||
{SPR_SSPK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_SSPK5
|
||||
|
||||
// Freed Birdie
|
||||
{SPR_BIRD, 0, 4, {NULL}, 0, 0, S_BIRD2}, // S_BIRD1
|
||||
|
@ -2535,6 +2536,9 @@ state_t states[NUMSTATES] =
|
|||
{SPR_RPOP, FF_FULLBRIGHT|2, 5, {NULL}, 0, 0, S_RANDOMITEMPOP4}, // S_RANDOMITEMPOP3
|
||||
{SPR_RPOP, FF_FULLBRIGHT|3, 5, {NULL}, 0, 0, S_NULL}, // S_RANDOMITEMPOP4
|
||||
|
||||
|
||||
{SPR_NULL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMICON
|
||||
|
||||
{SPR_SGNS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1
|
||||
{SPR_SGNS, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2
|
||||
{SPR_SGNS, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_SIGNSPARK4}, // S_SIGNSPARK3
|
||||
|
@ -2594,6 +2598,8 @@ state_t states[NUMSTATES] =
|
|||
{SPR_KFRE, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_KARTFIRE8}, // S_KARTFIRE7
|
||||
{SPR_KFRE, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_NULL}, // S_KARTFIRE8
|
||||
|
||||
{SPR_AIDU, FF_ANIMATE|FF_PAPERSPRITE, 5*2, {NULL}, 5, 2, S_NULL}, // S_KARTAIZDRIFTSTRAT
|
||||
|
||||
{SPR_KINV, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL2}, // S_KARTINVULN_SMALL1
|
||||
{SPR_KINV, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL3}, // S_KARTINVULN_SMALL2
|
||||
{SPR_KINV, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL4}, // S_KARTINVULN_SMALL3
|
||||
|
@ -2777,30 +2783,30 @@ state_t states[NUMSTATES] =
|
|||
{SPR_LIGH, 2, 2, {NULL}, 0, 0, S_LIGHTNING4}, // S_LIGHTNING3
|
||||
{SPR_LIGH, 3, 2, {NULL}, 0, 0, S_NULL}, // S_LIGHTNING4
|
||||
|
||||
{SPR_THNS, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_THUNDERSHIELD2}, // S_THUNDERSHIELD1
|
||||
{SPR_THNS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_THUNDERSHIELD3}, // S_THUNDERSHIELD2
|
||||
{SPR_THNS, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_THUNDERSHIELD4}, // S_THUNDERSHIELD3
|
||||
{SPR_THNS, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_THUNDERSHIELD5}, // S_THUNDERSHIELD4
|
||||
{SPR_THNS, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_THUNDERSHIELD6}, // S_THUNDERSHIELD5
|
||||
{SPR_THNS, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_THUNDERSHIELD7}, // S_THUNDERSHIELD6
|
||||
{SPR_THNS, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_THUNDERSHIELD8}, // S_THUNDERSHIELD7
|
||||
{SPR_THNS, FF_FULLBRIGHT|7, 2, {NULL}, 0, 0, S_THUNDERSHIELD9}, // S_THUNDERSHIELD8
|
||||
{SPR_THNS, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_THUNDERSHIELD10}, // S_THUNDERSHIELD9
|
||||
{SPR_THNS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_THUNDERSHIELD11}, // S_THUNDERSHIELD10
|
||||
{SPR_THNS, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_THUNDERSHIELD12}, // S_THUNDERSHIELD11
|
||||
{SPR_THNS, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_THUNDERSHIELD13}, // S_THUNDERSHIELD12
|
||||
{SPR_THNS, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_THUNDERSHIELD14}, // S_THUNDERSHIELD13
|
||||
{SPR_THNS, FF_FULLBRIGHT|7, 2, {NULL}, 0, 0, S_THUNDERSHIELD15}, // S_THUNDERSHIELD14
|
||||
{SPR_THNS, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_THUNDERSHIELD16}, // S_THUNDERSHIELD15
|
||||
{SPR_THNS, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_THUNDERSHIELD17}, // S_THUNDERSHIELD16
|
||||
{SPR_THNS, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_THUNDERSHIELD18}, // S_THUNDERSHIELD17
|
||||
{SPR_THNS, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_THUNDERSHIELD19}, // S_THUNDERSHIELD18
|
||||
{SPR_THNS, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_THUNDERSHIELD20}, // S_THUNDERSHIELD19
|
||||
{SPR_THNS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_THUNDERSHIELD21}, // S_THUNDERSHIELD20
|
||||
{SPR_THNS, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_THUNDERSHIELD22}, // S_THUNDERSHIELD21
|
||||
{SPR_THNS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_THUNDERSHIELD23}, // S_THUNDERSHIELD22
|
||||
{SPR_THNS, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_THUNDERSHIELD24}, // S_THUNDERSHIELD23
|
||||
{SPR_THNS, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_THUNDERSHIELD1}, // S_THUNDERSHIELD24
|
||||
{SPR_THNS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_THUNDERSHIELD2}, // S_THUNDERSHIELD1
|
||||
{SPR_THNS, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_THUNDERSHIELD3}, // S_THUNDERSHIELD2
|
||||
{SPR_THNS, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_THUNDERSHIELD4}, // S_THUNDERSHIELD3
|
||||
{SPR_THNS, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_THUNDERSHIELD5}, // S_THUNDERSHIELD4
|
||||
{SPR_THNS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_THUNDERSHIELD6}, // S_THUNDERSHIELD5
|
||||
{SPR_THNS, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_THUNDERSHIELD7}, // S_THUNDERSHIELD6
|
||||
{SPR_THNS, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_THUNDERSHIELD8}, // S_THUNDERSHIELD7
|
||||
{SPR_THNS, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_THUNDERSHIELD9}, // S_THUNDERSHIELD8
|
||||
{SPR_THNS, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_THUNDERSHIELD10}, // S_THUNDERSHIELD9
|
||||
{SPR_THNS, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_THUNDERSHIELD11}, // S_THUNDERSHIELD10
|
||||
{SPR_THNS, FF_FULLBRIGHT|7, 2, {NULL}, 0, 0, S_THUNDERSHIELD12}, // S_THUNDERSHIELD11
|
||||
{SPR_THNS, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_THUNDERSHIELD13}, // S_THUNDERSHIELD12
|
||||
{SPR_THNS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_THUNDERSHIELD14}, // S_THUNDERSHIELD13
|
||||
{SPR_THNS, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_THUNDERSHIELD15}, // S_THUNDERSHIELD14
|
||||
{SPR_THNS, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_THUNDERSHIELD16}, // S_THUNDERSHIELD15
|
||||
{SPR_THNS, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_THUNDERSHIELD17}, // S_THUNDERSHIELD16
|
||||
{SPR_THNS, FF_FULLBRIGHT|7, 2, {NULL}, 0, 0, S_THUNDERSHIELD18}, // S_THUNDERSHIELD17
|
||||
{SPR_THNS, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_THUNDERSHIELD19}, // S_THUNDERSHIELD18
|
||||
{SPR_THNS, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_THUNDERSHIELD20}, // S_THUNDERSHIELD19
|
||||
{SPR_THNS, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_THUNDERSHIELD21}, // S_THUNDERSHIELD20
|
||||
{SPR_THNS, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_THUNDERSHIELD22}, // S_THUNDERSHIELD21
|
||||
{SPR_THNS, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_THUNDERSHIELD23}, // S_THUNDERSHIELD22
|
||||
{SPR_THNS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_THUNDERSHIELD24}, // S_THUNDERSHIELD23
|
||||
{SPR_THNS, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_THUNDERSHIELD1}, // S_THUNDERSHIELD24
|
||||
|
||||
{SPR_SINK, 0, 1, {A_SmokeTrailer}, MT_SINKTRAIL, 0, S_SINK}, // S_SINK
|
||||
{SPR_SINK, 0|FF_TRANS80|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_SINK_SHIELD}, // S_SINK_SHIELD
|
||||
|
@ -2824,18 +2830,15 @@ state_t states[NUMSTATES] =
|
|||
{SPR_POKE, 3, 2, {A_MoveAbsolute}, 180, 2, S_POKEY5}, // S_POKEY8
|
||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_POKEYIDLE
|
||||
|
||||
{SPR_NULL, 0, 1, {A_RandomStateRange}, S_AUDIENCE_TOAD1, S_AUDIENCE_SNIF1, S_RANDOMAUDIENCE}, // S_RANDOMAUDIENCE
|
||||
{SPR_NULL, 0, 1, {A_RandomStateRange}, S_AUDIENCE_CHAO_CHEER1, S_AUDIENCE_CHAO_CHEER2, S_RANDOMAUDIENCE}, // S_RANDOMAUDIENCE
|
||||
|
||||
{SPR_AUDI, 0, 5, {NULL}, 0, 0, S_AUDIENCE_TOAD2}, // S_AUDIENCE_TOAD1
|
||||
{SPR_AUDI, 1, 20, {A_BunnyHop}, 7, 0, S_AUDIENCE_TOAD1}, // S_AUDIENCE_TOAD2
|
||||
{SPR_AUDI, 2, 5, {NULL}, 0, 0, S_AUDIENCE_BOO2}, // S_AUDIENCE_BOO1
|
||||
{SPR_AUDI, 3, 20, {A_BunnyHop}, 7, 0, S_AUDIENCE_BOO1}, // S_AUDIENCE_BOO2
|
||||
{SPR_AUDI, 4, 5, {NULL}, 0, 0, S_AUDIENCE_GMBA2}, // S_AUDIENCE_GMBA1
|
||||
{SPR_AUDI, 5, 20, {A_BunnyHop}, 7, 0, S_AUDIENCE_GMBA1}, // S_AUDIENCE_GMBA2
|
||||
{SPR_AUDI, 6, 5, {NULL}, 0, 0, S_AUDIENCE_SHYG2}, // S_AUDIENCE_SHYG1
|
||||
{SPR_AUDI, 7, 20, {A_BunnyHop}, 7, 0, S_AUDIENCE_SHYG1}, // S_AUDIENCE_SHYG2
|
||||
{SPR_AUDI, 8, 5, {NULL}, 0, 0, S_AUDIENCE_SNIF2}, // S_AUDIENCE_SNIF1
|
||||
{SPR_AUDI, 9, 20, {A_BunnyHop}, 7, 0, S_AUDIENCE_SNIF1}, // S_AUDIENCE_SNIF2
|
||||
{SPR_AUDI, 0, 5, {NULL}, 0, 0, S_AUDIENCE_CHAO_CHEER2}, // S_AUDIENCE_CHAO_CHEER1
|
||||
{SPR_AUDI, 1, 20, {A_BunnyHop}, 7, 0, S_AUDIENCE_CHAO_CHEER1}, // S_AUDIENCE_CHAO_CHEER2
|
||||
|
||||
{SPR_AUDI, 2, 5, {NULL}, 0, 0, S_AUDIENCE_CHAO_WIN2}, // S_AUDIENCE_CHAO_WIN1
|
||||
{SPR_AUDI, 3, 25, {A_BunnyHop}, 10, 0, S_AUDIENCE_CHAO_WIN1}, // S_AUDIENCE_CHAO_WIN2
|
||||
|
||||
{SPR_AUDI, 4|FF_ANIMATE, -1, {NULL}, 1, 17, S_NULL}, // S_AUDIENCE_CHAO_LOSE
|
||||
|
||||
{SPR_AUDI, 10, -1, {NULL}, 0, 0, S_NULL}, // S_FANCHAR_KOTE
|
||||
{SPR_AUDI, 11, -1, {NULL}, 0, 0, S_NULL}, // S_FANCHAR_RYAN
|
||||
|
@ -3005,6 +3008,57 @@ state_t states[NUMSTATES] =
|
|||
{SPR_RNDM, FF_ANIMATE, -1, {NULL}, 23, 3, S_NULL}, // S_PLAYERITEM
|
||||
|
||||
{SPR_PBOM, 4, -1, {NULL}, 0, 0, S_NULL}, // S_KARMAWHEEL
|
||||
|
||||
// Oh no it's annoying lightning states.......
|
||||
// Lightning Sparks (it's the ones we'll use for the radius)
|
||||
{SPR_KSPK, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK2}, // S_KSPARK1
|
||||
{SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK3}, // S_KSPARK2
|
||||
{SPR_KSPK, FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK4}, // S_KSPARK3
|
||||
{SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK5}, // S_KSPARK4
|
||||
{SPR_KSPK, FF_FULLBRIGHT|2, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK6}, // S_KSPARK5
|
||||
{SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK7}, // S_KSPARK6
|
||||
{SPR_KSPK, FF_FULLBRIGHT|3, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK8}, // S_KSPARK7
|
||||
{SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK9}, // S_KSPARK8
|
||||
{SPR_KSPK, FF_TRANS40|FF_FULLBRIGHT|4, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK10}, // S_KSPARK9
|
||||
{SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK11}, // S_KSPARK10
|
||||
{SPR_KSPK, FF_TRANS50|FF_FULLBRIGHT|5, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK12}, // S_KSPARK11
|
||||
{SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK13}, // S_KSPARK12
|
||||
{SPR_KSPK, FF_TRANS60|FF_FULLBRIGHT|6, 2, {A_LightningFollowPlayer}, 0, 0, S_NULL}, // S_KSPARK13
|
||||
|
||||
// The straight bolt...
|
||||
{SPR_LZI1, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO12}, // S_LZIO11
|
||||
{SPR_NULL, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO13}, // S_LZIO12
|
||||
{SPR_LZI1, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO14}, // S_LZIO13
|
||||
{SPR_LZI1, FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO15}, // S_LZIO14
|
||||
{SPR_NULL, FF_FULLBRIGHT, 4, {A_LightningFollowPlayer}, 0, 0, S_LZIO16}, // S_LZIO15
|
||||
{SPR_LZI1, FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO17}, // S_LZIO16
|
||||
{SPR_NULL, 0, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO18}, // S_LZIO17
|
||||
{SPR_LZI1, FF_TRANS50|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO19}, // S_LZIO18
|
||||
{SPR_LZI1, FF_TRANS70|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_NULL}, // S_LZIO19
|
||||
|
||||
{SPR_NULL, FF_FULLBRIGHT, 6, {A_LightningFollowPlayer}, 0, 0, S_LZIO22}, // S_LZIO21
|
||||
{SPR_LZI2, FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO23}, // S_LZIO22
|
||||
{SPR_LZI2, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO24}, // S_LZIO23
|
||||
{SPR_NULL, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO25}, // S_LZIO24
|
||||
{SPR_NULL, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO26}, // S_LZIO25
|
||||
{SPR_NULL, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO27}, // S_LZIO26
|
||||
{SPR_LZI2, FF_TRANS30|FF_FULLBRIGHT|2, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO28}, // S_LZIO27
|
||||
{SPR_NULL, 0, 4, {A_LightningFollowPlayer}, 0, 0, S_LZIO29}, // S_LZIO28
|
||||
{SPR_LZI2, FF_TRANS70|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_NULL}, // S_LZIO29
|
||||
|
||||
// The slanted bolt. Man these states are boring as all heck to do.
|
||||
{SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT2}, // S_KLIT1
|
||||
{SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT3}, // S_KLIT2
|
||||
{SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE|1, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT4}, // S_KLIT3
|
||||
{SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT5}, // S_KLIT4
|
||||
{SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE|2, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT6}, // S_KLIT5
|
||||
{SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT7}, // S_KLIT6
|
||||
{SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE|3, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT8}, // S_KLIT7
|
||||
{SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT9}, // S_KLIT8
|
||||
{SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE|4, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT10}, // S_KLIT9
|
||||
{SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT11}, // S_KLIT10
|
||||
{SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE|5, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT12}, // S_KLIT11
|
||||
{SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT1}, // S_KLIT12
|
||||
|
||||
#ifdef SEENAMES
|
||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
|
||||
|
@ -4035,7 +4089,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
4, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY, // flags
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -14397,6 +14451,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FLOATINGITEM
|
||||
-1, // doomednum
|
||||
S_ITEMICON, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_mcitm1, // deathsound
|
||||
0, // speed
|
||||
24*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SLIDEME|MF_SPECIAL|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_SIGNSPARKLE
|
||||
-1, // doomednum
|
||||
S_SIGNSPARK1, // spawnstate
|
||||
|
@ -14559,6 +14640,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_AIZDRIFTSTRAT
|
||||
-1, // doomednum
|
||||
S_KARTAIZDRIFTSTRAT,// spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
8, // speed
|
||||
14*FRACUNIT, // radius
|
||||
14*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_SPARKLETRAIL
|
||||
-1, // doomednum
|
||||
S_KARTINVULN_SMALL1, // spawnstate
|
||||
|
@ -14738,7 +14846,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_kc2e, // deathsound
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
|
@ -14819,7 +14927,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_s3k5d, // deathsound
|
||||
64*FRACUNIT, // speed
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
|
@ -15305,7 +15413,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
8, // speed
|
||||
16*FRACUNIT, // radius
|
||||
20*FRACUNIT, // radius
|
||||
56*FRACUNIT, // height
|
||||
1, // display offset
|
||||
16, // mass
|
||||
|
@ -15548,8 +15656,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
8, // speed
|
||||
16*FRACUNIT, // radius
|
||||
40*FRACUNIT, // height
|
||||
8*FRACUNIT, // radius
|
||||
20*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
|
|
81
src/info.h
81
src/info.h
|
@ -168,6 +168,7 @@ void A_JawzChase(); // SRB2kart
|
|||
void A_JawzExplode(); // SRB2kart
|
||||
void A_MineExplode(); // SRB2kart
|
||||
void A_BallhogExplode(); // SRB2kart
|
||||
void A_LightningFollowPlayer(); // SRB2kart: Lightning shield effect player chasing
|
||||
void A_OrbitNights();
|
||||
void A_GhostMe();
|
||||
void A_SetObjectState();
|
||||
|
@ -644,8 +645,15 @@ typedef enum sprite
|
|||
SPR_PBOM, // player bomb
|
||||
SPR_RETI, // player reticule
|
||||
|
||||
SPR_VIEW, // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw!
|
||||
SPR_AIDU,
|
||||
|
||||
SPR_KSPK, // Spark radius for the lightning shield
|
||||
SPR_LZI1, // Lightning that falls on the player for lightning shield
|
||||
SPR_LZI2, // ditto
|
||||
SPR_KLIT, // You have a twisted mind. But this actually is for the diagonal lightning.
|
||||
|
||||
SPR_VIEW, // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw!
|
||||
|
||||
SPR_FIRSTFREESLOT,
|
||||
SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
|
||||
NUMSPRITES
|
||||
|
@ -3051,6 +3059,8 @@ typedef enum state
|
|||
S_RANDOMITEMPOP4,
|
||||
//}
|
||||
|
||||
S_ITEMICON,
|
||||
|
||||
// Signpost sparkles
|
||||
S_SIGNSPARK1,
|
||||
S_SIGNSPARK2,
|
||||
|
@ -3116,6 +3126,9 @@ typedef enum state
|
|||
S_KARTFIRE7,
|
||||
S_KARTFIRE8,
|
||||
|
||||
// Angel Island Drift Strat Dust (what a mouthful!)
|
||||
S_KARTAIZDRIFTSTRAT,
|
||||
|
||||
// Invincibility Sparks
|
||||
S_KARTINVULN_SMALL1,
|
||||
S_KARTINVULN_SMALL2,
|
||||
|
@ -3364,16 +3377,11 @@ typedef enum state
|
|||
|
||||
// Audience Members
|
||||
S_RANDOMAUDIENCE,
|
||||
S_AUDIENCE_TOAD1,
|
||||
S_AUDIENCE_TOAD2,
|
||||
S_AUDIENCE_BOO1,
|
||||
S_AUDIENCE_BOO2,
|
||||
S_AUDIENCE_GMBA1,
|
||||
S_AUDIENCE_GMBA2,
|
||||
S_AUDIENCE_SHYG1,
|
||||
S_AUDIENCE_SHYG2,
|
||||
S_AUDIENCE_SNIF1,
|
||||
S_AUDIENCE_SNIF2,
|
||||
S_AUDIENCE_CHAO_CHEER1,
|
||||
S_AUDIENCE_CHAO_CHEER2,
|
||||
S_AUDIENCE_CHAO_WIN1,
|
||||
S_AUDIENCE_CHAO_WIN2,
|
||||
S_AUDIENCE_CHAO_LOSE,
|
||||
|
||||
S_FANCHAR_KOTE,
|
||||
S_FANCHAR_RYAN,
|
||||
|
@ -3548,6 +3556,54 @@ typedef enum state
|
|||
S_PLAYERITEM,
|
||||
|
||||
S_KARMAWHEEL,
|
||||
|
||||
// Thunder shield use stuff;
|
||||
S_KSPARK1, // Sparkling Radius
|
||||
S_KSPARK2,
|
||||
S_KSPARK3,
|
||||
S_KSPARK4,
|
||||
S_KSPARK5,
|
||||
S_KSPARK6,
|
||||
S_KSPARK7,
|
||||
S_KSPARK8,
|
||||
S_KSPARK9,
|
||||
S_KSPARK10,
|
||||
S_KSPARK11,
|
||||
S_KSPARK12,
|
||||
S_KSPARK13, // ... that's an awful lot.
|
||||
|
||||
S_LZIO11, // Straight lightning bolt
|
||||
S_LZIO12,
|
||||
S_LZIO13,
|
||||
S_LZIO14,
|
||||
S_LZIO15,
|
||||
S_LZIO16,
|
||||
S_LZIO17,
|
||||
S_LZIO18,
|
||||
S_LZIO19,
|
||||
|
||||
S_LZIO21, // Straight lightning bolt (flipped)
|
||||
S_LZIO22,
|
||||
S_LZIO23,
|
||||
S_LZIO24,
|
||||
S_LZIO25,
|
||||
S_LZIO26,
|
||||
S_LZIO27,
|
||||
S_LZIO28,
|
||||
S_LZIO29,
|
||||
|
||||
S_KLIT1, // Diagonal lightning. No, it not being straight doesn't make it gay.
|
||||
S_KLIT2,
|
||||
S_KLIT3,
|
||||
S_KLIT4,
|
||||
S_KLIT5,
|
||||
S_KLIT6,
|
||||
S_KLIT7,
|
||||
S_KLIT8,
|
||||
S_KLIT9,
|
||||
S_KLIT10,
|
||||
S_KLIT11,
|
||||
S_KLIT12,
|
||||
|
||||
#ifdef SEENAMES
|
||||
S_NAMECHECK,
|
||||
|
@ -4082,6 +4138,8 @@ typedef enum mobj_type
|
|||
MT_BLUEDIAG,
|
||||
MT_RANDOMITEM,
|
||||
MT_RANDOMITEMPOP,
|
||||
MT_FLOATINGITEM,
|
||||
|
||||
MT_SIGNSPARKLE,
|
||||
|
||||
MT_FASTLINE,
|
||||
|
@ -4089,6 +4147,7 @@ typedef enum mobj_type
|
|||
MT_BOOSTFLAME,
|
||||
MT_BOOSTSMOKE,
|
||||
MT_SNEAKERTRAIL,
|
||||
MT_AIZDRIFTSTRAT,
|
||||
MT_SPARKLETRAIL,
|
||||
MT_INVULNFLASH,
|
||||
MT_WIPEOUTTRAIL,
|
||||
|
|
434
src/k_kart.c
434
src/k_kart.c
|
@ -439,6 +439,7 @@ void K_RegisterKartStuff(void)
|
|||
CV_RegisterVar(&cv_kartdebugamount);
|
||||
CV_RegisterVar(&cv_kartdebugshrink);
|
||||
CV_RegisterVar(&cv_kartdebugdistribution);
|
||||
CV_RegisterVar(&cv_kartdebughuddrop);
|
||||
|
||||
CV_RegisterVar(&cv_kartdebugcheckpoint);
|
||||
}
|
||||
|
@ -1140,7 +1141,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
|||
fx->eflags |= MFE_VERTICALFLIP;
|
||||
else
|
||||
fx->eflags &= ~MFE_VERTICALFLIP;
|
||||
fx->scale = mobj1->scale;
|
||||
P_SetScale(fx, mobj1->scale);
|
||||
|
||||
// Because this is done during collision now, rmomx and rmomy need to be recalculated
|
||||
// so that friction doesn't immediately decide to stop the player if they're at a standstill
|
||||
|
@ -1830,6 +1831,10 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem
|
|||
P_SetPlayerMobjState(player->mo, S_KART_SPIN);
|
||||
|
||||
player->kartstuff[k_instashield] = 15;
|
||||
if (cv_kartdebughuddrop.value)
|
||||
K_DropItems(player);
|
||||
else
|
||||
K_DropHnextList(player);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1899,6 +1904,10 @@ void K_SquishPlayer(player_t *player, mobj_t *source)
|
|||
P_PlayRinglossSound(player->mo);
|
||||
|
||||
player->kartstuff[k_instashield] = 15;
|
||||
if (cv_kartdebughuddrop.value)
|
||||
K_DropItems(player);
|
||||
else
|
||||
K_DropHnextList(player);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1976,6 +1985,10 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju
|
|||
}
|
||||
|
||||
player->kartstuff[k_instashield] = 15;
|
||||
//if (cv_kartdebughuddrop.value)
|
||||
K_DropItems(player);
|
||||
/*else
|
||||
K_DropHnextList(player);*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2051,6 +2064,10 @@ void K_StealBumper(player_t *player, player_t *victim, boolean force)
|
|||
victim->kartstuff[k_comebacktimer] = comebacktime;*/
|
||||
|
||||
victim->kartstuff[k_instashield] = 15;
|
||||
if (cv_kartdebughuddrop.value)
|
||||
K_DropItems(victim);
|
||||
else
|
||||
K_DropHnextList(victim);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2158,14 +2175,14 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
|
|||
{
|
||||
dust = P_SpawnMobj(source->x, source->y, source->z, MT_SMOKE);
|
||||
dust->angle = (ANGLE_180/16) * i;
|
||||
dust->scale = source->scale;
|
||||
P_SetScale(dust, source->scale);
|
||||
dust->destscale = source->scale*10;
|
||||
P_InstaThrust(dust, dust->angle, FixedMul(20*FRACUNIT, source->scale));
|
||||
|
||||
truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT,
|
||||
source->y + P_RandomRange(-radius, radius)*FRACUNIT,
|
||||
source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMEXPLODE);
|
||||
truc->scale = source->scale*2;
|
||||
P_SetScale(truc, source->scale);
|
||||
truc->destscale = source->scale*6;
|
||||
speed = FixedMul(10*FRACUNIT, source->scale)>>FRACBITS;
|
||||
truc->momx = P_RandomRange(-speed, speed)*FRACUNIT;
|
||||
|
@ -2180,7 +2197,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
|
|||
dust = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT,
|
||||
source->y + P_RandomRange(-radius, radius)*FRACUNIT,
|
||||
source->z + P_RandomRange(0, height)*FRACUNIT, MT_SMOKE);
|
||||
dust->scale = source->scale;
|
||||
P_SetScale(dust, source->scale);
|
||||
dust->destscale = source->scale*10;
|
||||
dust->tics = 30;
|
||||
dust->momz = P_RandomRange(FixedMul(3*FRACUNIT, source->scale)>>FRACBITS, FixedMul(7*FRACUNIT, source->scale)>>FRACBITS)*FRACUNIT;
|
||||
|
@ -2188,7 +2205,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
|
|||
truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT,
|
||||
source->y + P_RandomRange(-radius, radius)*FRACUNIT,
|
||||
source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMPARTICLE);
|
||||
truc->scale = source->scale;
|
||||
P_SetScale(truc, source->scale);
|
||||
truc->destscale = source->scale*5;
|
||||
speed = FixedMul(20*FRACUNIT, source->scale)>>FRACBITS;
|
||||
truc->momx = P_RandomRange(-speed, speed)*FRACUNIT;
|
||||
|
@ -2377,6 +2394,41 @@ static void K_SpawnDriftSparks(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
static void K_SpawnAIZDust(player_t *player)
|
||||
{
|
||||
fixed_t newx;
|
||||
fixed_t newy;
|
||||
mobj_t *spark;
|
||||
angle_t travelangle;
|
||||
|
||||
I_Assert(player != NULL);
|
||||
I_Assert(player->mo != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(player->mo));
|
||||
|
||||
if (leveltime % 2 == 1)
|
||||
return;
|
||||
|
||||
if (!P_IsObjectOnGround(player->mo))
|
||||
return;
|
||||
|
||||
travelangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
|
||||
|
||||
{
|
||||
newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle - (player->kartstuff[k_aizdriftstrat]*ANGLE_45), FixedMul(24*FRACUNIT, player->mo->scale));
|
||||
newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle - (player->kartstuff[k_aizdriftstrat]*ANGLE_45), FixedMul(24*FRACUNIT, player->mo->scale));
|
||||
spark = P_SpawnMobj(newx, newy, player->mo->z, MT_AIZDRIFTSTRAT);
|
||||
|
||||
spark->angle = travelangle+(player->kartstuff[k_aizdriftstrat]*ANGLE_90);
|
||||
P_SetScale(spark, (spark->destscale = (3*player->mo->scale)>>2));
|
||||
|
||||
spark->momx = (6*player->mo->momx)/5;
|
||||
spark->momy = (6*player->mo->momy)/5;
|
||||
//spark->momz = player->mo->momz/2;
|
||||
|
||||
K_MatchGenericExtraFlags(spark, player->mo);
|
||||
}
|
||||
}
|
||||
|
||||
void K_SpawnBoostTrail(player_t *player)
|
||||
{
|
||||
fixed_t newx;
|
||||
|
@ -2551,7 +2603,7 @@ void K_DriftDustHandling(mobj_t *spawner)
|
|||
dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*FRACUNIT/4);
|
||||
dust->momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*FRACUNIT/4);
|
||||
dust->momz = P_MobjFlip(spawner) * P_RandomRange(1, 4)<<FRACBITS;
|
||||
dust->scale = spawner->scale/2;
|
||||
P_SetScale(dust, spawner->scale/2);
|
||||
dust->destscale = spawner->scale * 3;
|
||||
|
||||
if (leveltime % 6 == 0)
|
||||
|
@ -2790,13 +2842,59 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
|
|||
return mo;
|
||||
}
|
||||
|
||||
#define THUNDERRADIUS 320
|
||||
|
||||
static void K_DoThunderShield(player_t *player)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s3k45);
|
||||
mobj_t *mo;
|
||||
int i = 0;
|
||||
fixed_t sx;
|
||||
fixed_t sy;
|
||||
|
||||
S_StartSound(player->mo, sfx_zio3);
|
||||
//player->kartstuff[k_thunderanim] = 35;
|
||||
P_NukeEnemies(player->mo, player->mo, RING_DIST/4);
|
||||
|
||||
// spawn vertical bolt
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK);
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
P_SetMobjState(mo, S_LZIO11);
|
||||
mo->color = SKINCOLOR_TEAL;
|
||||
mo->scale = player->mo->scale*3 + (player->mo->scale/2);
|
||||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK);
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
P_SetMobjState(mo, S_LZIO21);
|
||||
mo->color = SKINCOLOR_CYAN;
|
||||
mo->scale = player->mo->scale*3 + (player->mo->scale/2);
|
||||
|
||||
// spawn horizontal bolts;
|
||||
for (i=0; i<7; i++)
|
||||
{
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK);
|
||||
mo->angle = P_RandomRange(0, 359)*ANG1;
|
||||
mo->fuse = P_RandomRange(20, 50);
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
P_SetMobjState(mo, S_KLIT1);
|
||||
}
|
||||
|
||||
// spawn the radius thing:
|
||||
angle_t an = ANGLE_22h;
|
||||
for (i=0; i<15; i++)
|
||||
{
|
||||
sx = player->mo->x + FixedMul((player->mo->scale*THUNDERRADIUS), FINECOSINE((an*i)>>ANGLETOFINESHIFT));
|
||||
sy = player->mo->y + FixedMul((player->mo->scale*THUNDERRADIUS), FINESINE((an*i)>>ANGLETOFINESHIFT));
|
||||
mo = P_SpawnMobj(sx, sy, player->mo->z, MT_THOK);
|
||||
mo-> angle = an*i;
|
||||
mo->extravalue1 = THUNDERRADIUS; // Used to know whether we should teleport by radius or something.
|
||||
mo->scale = player->mo->scale*3;
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
P_SetMobjState(mo, S_KSPARK1);
|
||||
}
|
||||
}
|
||||
|
||||
#undef THUNDERRADIUS
|
||||
|
||||
static void K_DoHyudoroSteal(player_t *player)
|
||||
{
|
||||
INT32 i, numplayers = 0;
|
||||
|
@ -3016,46 +3114,191 @@ killnext:
|
|||
}
|
||||
|
||||
// Just for firing/dropping items.
|
||||
void K_CleanHnextList(mobj_t *work)
|
||||
{
|
||||
mobj_t *nextwork;
|
||||
|
||||
if (!work)
|
||||
return;
|
||||
|
||||
work = work->hnext;
|
||||
|
||||
while (work && !P_MobjWasRemoved(work))
|
||||
{
|
||||
nextwork = work->hnext;
|
||||
|
||||
P_RemoveMobj(work);
|
||||
|
||||
work = nextwork;
|
||||
}
|
||||
}
|
||||
|
||||
// Ditto.
|
||||
void K_UpdateHnextList(player_t *player)
|
||||
void K_UpdateHnextList(player_t *player, boolean clean)
|
||||
{
|
||||
mobj_t *work = player->mo, *nextwork;
|
||||
|
||||
if (!work)
|
||||
return;
|
||||
|
||||
work = work->hnext;
|
||||
nextwork = work->hnext;
|
||||
|
||||
while (work && !P_MobjWasRemoved(work))
|
||||
while ((work = nextwork) && !P_MobjWasRemoved(work))
|
||||
{
|
||||
nextwork = work->hnext;
|
||||
|
||||
if (work->movedir > 0 && work->movedir > (UINT16)player->kartstuff[k_itemamount])
|
||||
P_RemoveMobj(work);
|
||||
if (!clean && (!work->movedir || work->movedir <= (UINT16)player->kartstuff[k_itemamount]))
|
||||
continue;
|
||||
|
||||
work = nextwork;
|
||||
P_RemoveMobj(work);
|
||||
}
|
||||
}
|
||||
|
||||
// For getting hit!
|
||||
void K_DropHnextList(player_t *player)
|
||||
{
|
||||
mobj_t *work = player->mo, *nextwork, *dropwork;
|
||||
INT32 flip;
|
||||
mobjtype_t type;
|
||||
boolean orbit, ponground;
|
||||
|
||||
if (!work)
|
||||
return;
|
||||
|
||||
flip = P_MobjFlip(player->mo);
|
||||
ponground = P_IsObjectOnGround(player->mo);
|
||||
|
||||
if (player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD && player->kartstuff[k_itemamount])
|
||||
{
|
||||
K_DoThunderShield(player);
|
||||
player->kartstuff[k_itemamount] = 0;
|
||||
player->kartstuff[k_itemtype] = KITEM_NONE;
|
||||
player->kartstuff[k_curshield] = 0;
|
||||
}
|
||||
|
||||
nextwork = work->hnext;
|
||||
|
||||
while ((work = nextwork) && !P_MobjWasRemoved(work))
|
||||
{
|
||||
nextwork = work->hnext;
|
||||
|
||||
switch (work->type)
|
||||
{
|
||||
// Kart orbit items
|
||||
case MT_ORBINAUT_SHIELD:
|
||||
orbit = true;
|
||||
type = MT_ORBINAUT;
|
||||
break;
|
||||
case MT_JAWZ_SHIELD:
|
||||
orbit = true;
|
||||
type = MT_JAWZ_DUD;
|
||||
break;
|
||||
// Kart trailing items
|
||||
case MT_BANANA_SHIELD:
|
||||
orbit = false;
|
||||
type = MT_BANANA;
|
||||
break;
|
||||
case MT_SSMINE_SHIELD:
|
||||
orbit = false;
|
||||
type = MT_SSMINE;
|
||||
break;
|
||||
case MT_FAKESHIELD:
|
||||
orbit = false;
|
||||
type = MT_FAKEITEM;
|
||||
break;
|
||||
// intentionally do nothing
|
||||
case MT_SINK_SHIELD:
|
||||
return;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
dropwork = P_SpawnMobj(work->x, work->y, work->z, type);
|
||||
P_SetTarget(&dropwork->target, player->mo);
|
||||
dropwork->angle = work->angle;
|
||||
dropwork->flags2 = work->flags2;
|
||||
dropwork->flags |= MF_NOCLIPTHING;
|
||||
dropwork->floorz = work->floorz;
|
||||
dropwork->ceilingz = work->ceilingz;
|
||||
|
||||
if (ponground)
|
||||
{
|
||||
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
|
||||
// This should set it for FOFs
|
||||
//P_TeleportMove(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing
|
||||
|
||||
if (flip == 1)
|
||||
{
|
||||
if (dropwork->floorz > dropwork->target->z - dropwork->height)
|
||||
{
|
||||
dropwork->z = dropwork->floorz;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dropwork->ceilingz < dropwork->target->z + dropwork->target->height + dropwork->height)
|
||||
{
|
||||
dropwork->z = dropwork->ceilingz - dropwork->height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (orbit) // splay out
|
||||
{
|
||||
dropwork->flags2 |= MF2_AMBUSH;
|
||||
dropwork->z += flip;
|
||||
dropwork->momx = player->mo->momx>>1;
|
||||
dropwork->momy = player->mo->momy>>1;
|
||||
dropwork->momz = 3*flip*mapheaderinfo[gamemap-1]->mobj_scale;
|
||||
P_Thrust(dropwork, work->angle - ANGLE_90, 6*(mapheaderinfo[gamemap-1]->mobj_scale));
|
||||
dropwork->movecount = 2;
|
||||
dropwork->movedir = work->angle - ANGLE_90;
|
||||
P_SetMobjState(dropwork, dropwork->info->deathstate);
|
||||
dropwork->tics = -1;
|
||||
if (type == MT_JAWZ_DUD)
|
||||
dropwork->z += 20*flip*dropwork->scale;
|
||||
else
|
||||
{
|
||||
dropwork->color = work->color;
|
||||
dropwork->angle -= ANGLE_90;
|
||||
}
|
||||
}
|
||||
else // plop on the ground
|
||||
{
|
||||
dropwork->flags &= ~MF_NOCLIPTHING;
|
||||
dropwork->threshold = 10;
|
||||
}
|
||||
|
||||
P_RemoveMobj(work);
|
||||
}
|
||||
|
||||
{
|
||||
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
|
||||
P_SetTarget(&player->mo->hnext, NULL);
|
||||
player->kartstuff[k_bananadrag] = 0;
|
||||
if (player->kartstuff[k_eggmanheld])
|
||||
player->kartstuff[k_eggmanheld] = 0;
|
||||
else if (player->kartstuff[k_itemheld])
|
||||
{
|
||||
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
|
||||
player->kartstuff[k_itemtype] = KITEM_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For getting EXTRA hit!
|
||||
void K_DropItems(player_t *player)
|
||||
{
|
||||
boolean thunderhack = (player->kartstuff[k_curshield] && player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD);
|
||||
|
||||
if (thunderhack)
|
||||
player->kartstuff[k_itemtype] = KITEM_NONE;
|
||||
|
||||
K_DropHnextList(player);
|
||||
|
||||
if (player->mo && player->kartstuff[k_itemamount])
|
||||
{
|
||||
mobj_t *drop = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FLOATINGITEM);
|
||||
P_SetScale(drop, drop->scale>>4);
|
||||
drop->destscale = (3*drop->destscale)/2;;
|
||||
|
||||
drop->angle = player->mo->angle + ANGLE_90;
|
||||
drop->momx = player->mo->momx>>1;
|
||||
drop->momy = player->mo->momy>>1;
|
||||
P_Thrust(drop,
|
||||
FixedAngle(P_RandomFixed()*180) + player->mo->angle + ANGLE_90,
|
||||
8*(mapheaderinfo[gamemap-1]->mobj_scale));
|
||||
drop->momz = P_MobjFlip(player->mo)*3*(mapheaderinfo[gamemap-1]->mobj_scale);
|
||||
|
||||
drop->threshold = (thunderhack ? KITEM_THUNDERSHIELD : player->kartstuff[k_itemtype]);
|
||||
drop->movecount = player->kartstuff[k_itemamount];
|
||||
|
||||
drop->flags |= MF_NOCLIPTHING;
|
||||
}
|
||||
|
||||
K_StripItems(player);
|
||||
}
|
||||
|
||||
// When an item in the hnext chain dies.
|
||||
void K_RepairOrbitChain(mobj_t *orbit)
|
||||
{
|
||||
|
@ -3714,7 +3957,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
void K_KartPlayerAfterThink(player_t *player)
|
||||
{
|
||||
if (player->kartstuff[k_invincibilitytimer]
|
||||
if (player->kartstuff[k_curshield]
|
||||
|| player->kartstuff[k_invincibilitytimer]
|
||||
|| (player->kartstuff[k_growshrinktimer] != 0 && player->kartstuff[k_growshrinktimer] % 5 == 4)) // 4 instead of 0 because this is afterthink!
|
||||
{
|
||||
player->mo->frame |= FF_FULLBRIGHT;
|
||||
|
@ -3901,16 +4145,14 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
{
|
||||
// Starting left drift
|
||||
player->kartstuff[k_drift] = 1;
|
||||
player->kartstuff[k_driftend] = 0;
|
||||
player->kartstuff[k_driftcharge] = 0;
|
||||
player->kartstuff[k_driftend] = player->kartstuff[k_driftcharge] = 0;
|
||||
}
|
||||
else if ((player->cmd.driftturn < 0) && player->speed > FixedMul(10<<16, player->mo->scale) && player->kartstuff[k_jmp] == 1
|
||||
&& (player->kartstuff[k_drift] == 0 || player->kartstuff[k_driftend] == 1)) // && player->kartstuff[k_drift] != -1)
|
||||
{
|
||||
// Starting right drift
|
||||
player->kartstuff[k_drift] = -1;
|
||||
player->kartstuff[k_driftend] = 0;
|
||||
player->kartstuff[k_driftcharge] = 0;
|
||||
player->kartstuff[k_driftend] = player->kartstuff[k_driftcharge] = 0;
|
||||
}
|
||||
else if (player->kartstuff[k_jmp] == 0) // || player->kartstuff[k_turndir] == 0)
|
||||
{
|
||||
|
@ -3969,9 +4211,20 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
if (player->kartstuff[k_spinouttimer] > 0 // banana peel
|
||||
|| player->speed < FixedMul(10<<16, player->mo->scale)) // you're too slow!
|
||||
{
|
||||
player->kartstuff[k_drift] = 0;
|
||||
player->kartstuff[k_driftcharge] = 0;
|
||||
player->kartstuff[k_drift] = player->kartstuff[k_driftcharge] = player->kartstuff[k_aizdriftstrat] = 0;
|
||||
}
|
||||
|
||||
if ((!player->kartstuff[k_sneakertimer])
|
||||
|| (!player->cmd.driftturn)
|
||||
|| (player->cmd.driftturn > 0) != (player->kartstuff[k_aizdriftstrat] > 0))
|
||||
{
|
||||
if (!player->kartstuff[k_drift])
|
||||
player->kartstuff[k_aizdriftstrat] = 0;
|
||||
else
|
||||
player->kartstuff[k_aizdriftstrat] = ((player->kartstuff[k_drift] > 0) ? 1 : -1);
|
||||
}
|
||||
else if (player->kartstuff[k_aizdriftstrat] && !player->kartstuff[k_drift])
|
||||
K_SpawnAIZDust(player);
|
||||
}
|
||||
//
|
||||
// K_KartUpdatePosition
|
||||
|
@ -3982,7 +4235,6 @@ static void K_KartUpdatePosition(player_t *player)
|
|||
fixed_t oldposition = player->kartstuff[k_position];
|
||||
fixed_t i, ppcd, pncd, ipcd, incd;
|
||||
fixed_t pmo, imo;
|
||||
thinker_t *th;
|
||||
mobj_t *mo;
|
||||
|
||||
if (player->spectator || !player->mo)
|
||||
|
@ -4007,16 +4259,8 @@ static void K_KartUpdatePosition(player_t *player)
|
|||
player->kartstuff[k_nextcheck] = players[i].kartstuff[k_nextcheck] = 0;
|
||||
|
||||
// This checks every thing on the map, and looks for MT_BOSS3WAYPOINT (the thing we're using for checkpoint wp's, for now)
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
for (mo = waypointcap; mo != NULL; mo = mo->tracer)
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj at all, shoo
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
|
||||
if (mo->type != MT_BOSS3WAYPOINT) // TODO: Change to 'MT_WAYPOINT'?
|
||||
continue;
|
||||
|
||||
pmo = P_AproxDistance(P_AproxDistance( mo->x - player->mo->x,
|
||||
mo->y - player->mo->y),
|
||||
mo->z - player->mo->z) / FRACUNIT;
|
||||
|
@ -4100,20 +4344,18 @@ static void K_KartUpdatePosition(player_t *player)
|
|||
//
|
||||
void K_StripItems(player_t *player)
|
||||
{
|
||||
player->kartstuff[k_itemtype] = 0;
|
||||
player->kartstuff[k_itemtype] = KITEM_NONE;
|
||||
player->kartstuff[k_itemamount] = 0;
|
||||
player->kartstuff[k_itemheld] = 0;
|
||||
|
||||
player->kartstuff[k_itemroulette] = 0;
|
||||
player->kartstuff[k_roulettetype] = 0;
|
||||
|
||||
player->kartstuff[k_rocketsneakertimer] = 0;
|
||||
player->kartstuff[k_invincibilitytimer] = 0;
|
||||
player->kartstuff[k_growshrinktimer] = 0;
|
||||
|
||||
if (!player->kartstuff[k_itemroulette] || player->kartstuff[k_roulettetype] != 2)
|
||||
{
|
||||
player->kartstuff[k_itemroulette] = 0;
|
||||
player->kartstuff[k_roulettetype] = 0;
|
||||
}
|
||||
player->kartstuff[k_eggmanheld] = 0;
|
||||
player->kartstuff[k_eggmanexplode] = 0;
|
||||
player->kartstuff[k_eggmanblame] = 0;
|
||||
|
||||
player->kartstuff[k_hyudorotimer] = 0;
|
||||
player->kartstuff[k_stealingtimer] = 0;
|
||||
|
@ -4125,7 +4367,19 @@ void K_StripItems(player_t *player)
|
|||
|
||||
player->kartstuff[k_sadtimer] = 0;
|
||||
|
||||
K_CleanHnextList(player->mo);
|
||||
K_UpdateHnextList(player, true);
|
||||
}
|
||||
|
||||
void K_StripOther(player_t *player)
|
||||
{
|
||||
player->kartstuff[k_itemroulette] = 0;
|
||||
player->kartstuff[k_roulettetype] = 0;
|
||||
|
||||
player->kartstuff[k_invincibilitytimer] = 0;
|
||||
player->kartstuff[k_growshrinktimer] = 0;
|
||||
|
||||
player->kartstuff[k_eggmanexplode] = 0;
|
||||
player->kartstuff[k_eggmanblame] = 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -4191,7 +4445,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
K_ThrowKartItem(player, false, MT_FAKEITEM, -1, 0);
|
||||
K_PlayAttackTaunt(player->mo);
|
||||
player->kartstuff[k_eggmanheld] = 0;
|
||||
K_CleanHnextList(player->mo);
|
||||
K_UpdateHnextList(player, true);
|
||||
}
|
||||
// Rocket Sneaker
|
||||
else if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO
|
||||
|
@ -4281,7 +4535,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
K_ThrowKartItem(player, false, MT_BANANA, -1, 0);
|
||||
K_PlayAttackTaunt(player->mo);
|
||||
player->kartstuff[k_itemamount]--;
|
||||
K_UpdateHnextList(player);
|
||||
K_UpdateHnextList(player, false);
|
||||
}
|
||||
break;
|
||||
case KITEM_EGGMAN:
|
||||
|
@ -4341,7 +4595,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
K_ThrowKartItem(player, true, MT_ORBINAUT, 1, 0);
|
||||
K_PlayAttackTaunt(player->mo);
|
||||
player->kartstuff[k_itemamount]--;
|
||||
K_UpdateHnextList(player);
|
||||
K_UpdateHnextList(player, false);
|
||||
}
|
||||
break;
|
||||
case KITEM_JAWZ:
|
||||
|
@ -4384,7 +4638,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
K_ThrowKartItem(player, true, MT_JAWZ_DUD, -1, 0);
|
||||
K_PlayAttackTaunt(player->mo);
|
||||
player->kartstuff[k_itemamount]--;
|
||||
K_UpdateHnextList(player);
|
||||
K_UpdateHnextList(player, false);
|
||||
}
|
||||
break;
|
||||
case KITEM_MINE:
|
||||
|
@ -4410,7 +4664,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
K_PlayAttackTaunt(player->mo);
|
||||
player->kartstuff[k_itemamount]--;
|
||||
player->kartstuff[k_itemheld] = 0;
|
||||
K_CleanHnextList(player->mo);
|
||||
K_UpdateHnextList(player, true);
|
||||
}
|
||||
break;
|
||||
case KITEM_BALLHOG:
|
||||
|
@ -4489,6 +4743,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
if (player->kartstuff[k_curshield] <= 0)
|
||||
{
|
||||
mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THUNDERSHIELD);
|
||||
P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2));
|
||||
P_SetTarget(&shield->target, player->mo);
|
||||
player->kartstuff[k_curshield] = 1;
|
||||
}
|
||||
|
@ -4539,7 +4794,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
K_PlayAttackTaunt(player->mo);
|
||||
player->kartstuff[k_itemamount]--;
|
||||
player->kartstuff[k_itemheld] = 0;
|
||||
K_CleanHnextList(player->mo);
|
||||
K_UpdateHnextList(player, true);
|
||||
}
|
||||
break;
|
||||
case KITEM_SAD:
|
||||
|
@ -4618,7 +4873,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
|
||||
if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) // dead in match? you da bomb
|
||||
{
|
||||
K_StripItems(player);
|
||||
K_DropItems(player); //K_StripItems(player);
|
||||
K_StripOther(player);
|
||||
player->mo->flags2 |= MF2_SHADOW;
|
||||
player->powers[pw_flashing] = player->kartstuff[k_comebacktimer];
|
||||
}
|
||||
|
@ -5275,52 +5531,52 @@ void K_LoadKartHUDGraphics(void)
|
|||
}
|
||||
|
||||
// For the item toggle menu
|
||||
const char *K_GetItemPatch(UINT8 item, boolean small)
|
||||
const char *K_GetItemPatch(UINT8 item, boolean tiny)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case KITEM_SNEAKER:
|
||||
case KRITEM_TRIPLESNEAKER:
|
||||
return (small ? "K_ISSHOE" : "K_ITSHOE");
|
||||
return (tiny ? "K_ISSHOE" : "K_ITSHOE");
|
||||
case KITEM_ROCKETSNEAKER:
|
||||
return (small ? "K_ISRSHE" : "K_ITRSHE");
|
||||
return (tiny ? "K_ISRSHE" : "K_ITRSHE");
|
||||
case KITEM_INVINCIBILITY:
|
||||
return (small ? "K_ISINV1" : "K_ITINV1");
|
||||
return (tiny ? "K_ISINV1" : "K_ITINV1");
|
||||
case KITEM_BANANA:
|
||||
case KRITEM_TRIPLEBANANA:
|
||||
case KRITEM_TENFOLDBANANA:
|
||||
return (small ? "K_ISBANA" : "K_ITBANA");
|
||||
return (tiny ? "K_ISBANA" : "K_ITBANA");
|
||||
case KITEM_EGGMAN:
|
||||
return (small ? "K_ISEGGM" : "K_ITEGGM");
|
||||
return (tiny ? "K_ISEGGM" : "K_ITEGGM");
|
||||
case KITEM_ORBINAUT:
|
||||
return (small ? "K_ISORBN" : "K_ITORB1");
|
||||
return (tiny ? "K_ISORBN" : "K_ITORB1");
|
||||
case KITEM_JAWZ:
|
||||
case KRITEM_DUALJAWZ:
|
||||
return (small ? "K_ISJAWZ" : "K_ITJAWZ");
|
||||
return (tiny ? "K_ISJAWZ" : "K_ITJAWZ");
|
||||
case KITEM_MINE:
|
||||
return (small ? "K_ISMINE" : "K_ITMINE");
|
||||
return (tiny ? "K_ISMINE" : "K_ITMINE");
|
||||
case KITEM_BALLHOG:
|
||||
return (small ? "K_ISBHOG" : "K_ITBHOG");
|
||||
return (tiny ? "K_ISBHOG" : "K_ITBHOG");
|
||||
case KITEM_SPB:
|
||||
return (small ? "K_ISSPB" : "K_ITSPB");
|
||||
return (tiny ? "K_ISSPB" : "K_ITSPB");
|
||||
case KITEM_GROW:
|
||||
return (small ? "K_ISGROW" : "K_ITGROW");
|
||||
return (tiny ? "K_ISGROW" : "K_ITGROW");
|
||||
case KITEM_SHRINK:
|
||||
return (small ? "K_ISSHRK" : "K_ITSHRK");
|
||||
return (tiny ? "K_ISSHRK" : "K_ITSHRK");
|
||||
case KITEM_THUNDERSHIELD:
|
||||
return (small ? "K_ISTHNS" : "K_ITTHNS");
|
||||
return (tiny ? "K_ISTHNS" : "K_ITTHNS");
|
||||
case KITEM_HYUDORO:
|
||||
return (small ? "K_ISHYUD" : "K_ITHYUD");
|
||||
return (tiny ? "K_ISHYUD" : "K_ITHYUD");
|
||||
case KITEM_POGOSPRING:
|
||||
return (small ? "K_ISPOGO" : "K_ITPOGO");
|
||||
return (tiny ? "K_ISPOGO" : "K_ITPOGO");
|
||||
case KITEM_KITCHENSINK:
|
||||
return (small ? "K_ISSINK" : "K_ITSINK");
|
||||
return (tiny ? "K_ISSINK" : "K_ITSINK");
|
||||
case KRITEM_TRIPLEORBINAUT:
|
||||
return (small ? "K_ISORBN" : "K_ITORB3");
|
||||
return (tiny ? "K_ISORBN" : "K_ITORB3");
|
||||
case KRITEM_QUADORBINAUT:
|
||||
return (small ? "K_ISORBN" : "K_ITORB4");
|
||||
return (tiny ? "K_ISORBN" : "K_ITORB4");
|
||||
default:
|
||||
return (small ? "K_ISSAD" : "K_ITSAD");
|
||||
return (tiny ? "K_ISSAD" : "K_ITSAD");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5603,10 +5859,10 @@ static void K_drawKartItem(void)
|
|||
case KITEM_JAWZ: localpatch = kp_jawz[offset]; break;
|
||||
case KITEM_MINE: localpatch = kp_mine[offset]; break;
|
||||
case KITEM_BALLHOG: localpatch = kp_ballhog[offset]; break;
|
||||
case KITEM_SPB: localpatch = kp_selfpropelledbomb[offset]; break;
|
||||
case KITEM_SPB: localpatch = kp_selfpropelledbomb[offset]; localbg = kp_itembg[offset+1]; break;
|
||||
case KITEM_GROW: localpatch = kp_grow[offset]; break;
|
||||
case KITEM_SHRINK: localpatch = kp_shrink[offset]; break;
|
||||
case KITEM_THUNDERSHIELD: localpatch = kp_thundershield[offset]; break;
|
||||
case KITEM_THUNDERSHIELD: localpatch = kp_thundershield[offset]; localbg = kp_itembg[offset+1]; break;
|
||||
case KITEM_HYUDORO: localpatch = kp_hyudoro[offset]; break;
|
||||
case KITEM_POGOSPRING: localpatch = kp_pogospring[offset]; break;
|
||||
case KITEM_KITCHENSINK: localpatch = kp_kitchensink[offset]; break;
|
||||
|
@ -6348,7 +6604,7 @@ static void K_drawKartMinimap(void)
|
|||
|
||||
// Draw the HUD only when playing in a level.
|
||||
// hu_stuff needs this, unlike st_stuff.
|
||||
if (!(Playing() && gamestate == GS_LEVEL))
|
||||
if (gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
if (stplyr != &players[displayplayer])
|
||||
|
|
|
@ -39,14 +39,16 @@ void K_DriftDustHandling(mobj_t *spawner);
|
|||
void K_DoSneaker(player_t *player, boolean doPFlag);
|
||||
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, boolean mute);
|
||||
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);
|
||||
void K_CleanHnextList(mobj_t *work);
|
||||
void K_UpdateHnextList(player_t *player);
|
||||
void K_UpdateHnextList(player_t *player, boolean clean);
|
||||
void K_DropHnextList(player_t *player);
|
||||
void K_RepairOrbitChain(mobj_t *orbit);
|
||||
player_t *K_FindJawzTarget(mobj_t *actor, player_t *source);
|
||||
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
|
||||
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
|
||||
fixed_t K_GetKartDriftSparkValue(player_t *player);
|
||||
void K_DropItems(player_t *player);
|
||||
void K_StripItems(player_t *player);
|
||||
void K_StripOther(player_t *player);
|
||||
void K_MomentumToFacing(player_t *player);
|
||||
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower);
|
||||
fixed_t K_GetKartAccel(player_t *player);
|
||||
|
@ -57,7 +59,7 @@ void K_CalculateBattleWanted(void);
|
|||
void K_CheckBumpers(void);
|
||||
void K_CheckSpectateStatus(void);
|
||||
|
||||
const char *K_GetItemPatch(UINT8 item, boolean small);
|
||||
const char *K_GetItemPatch(UINT8 item, boolean tiny);
|
||||
INT32 K_calcSplitFlags(INT32 snapflags);
|
||||
void K_LoadKartHUDGraphics(void);
|
||||
fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fixed_t my);
|
||||
|
|
668
src/m_menu.c
668
src/m_menu.c
|
@ -33,6 +33,9 @@
|
|||
#include "s_sound.h"
|
||||
#include "i_system.h"
|
||||
|
||||
// Addfile
|
||||
#include "filesrch.h"
|
||||
|
||||
#include "v_video.h"
|
||||
#include "i_video.h"
|
||||
#include "keys.h"
|
||||
|
@ -68,6 +71,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
|||
//int vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__) && (__GNUC__ >= 4)
|
||||
#define FIXUPO0
|
||||
#endif
|
||||
|
||||
#define SKULLXOFF -32
|
||||
#define LINEHEIGHT 16
|
||||
#define STRINGHEIGHT 8
|
||||
|
@ -75,7 +82,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
|||
#define SMALLLINEHEIGHT 8
|
||||
#define SLIDER_RANGE 10
|
||||
#define SLIDER_WIDTH (8*SLIDER_RANGE+6)
|
||||
#define MAXSTRINGLENGTH 32
|
||||
#define SERVERS_PER_PAGE 11
|
||||
|
||||
typedef enum
|
||||
|
@ -207,6 +213,8 @@ menu_t MessageDef;
|
|||
|
||||
menu_t SPauseDef;
|
||||
|
||||
#define lsheadingheight 16
|
||||
|
||||
// Sky Room
|
||||
//static void M_CustomLevelSelect(INT32 choice);
|
||||
//static void M_CustomWarp(INT32 choice);
|
||||
|
@ -323,9 +331,16 @@ menu_t OP_MonitorToggleDef;
|
|||
static void M_ScreenshotOptions(INT32 choice);
|
||||
static void M_EraseData(INT32 choice);
|
||||
|
||||
static void M_Addons(INT32 choice);
|
||||
static void M_AddonsOptions(INT32 choice);
|
||||
static patch_t *addonsp[NUM_EXT+5];
|
||||
|
||||
#define numaddonsshown 4
|
||||
|
||||
// Drawing functions
|
||||
static void M_DrawGenericMenu(void);
|
||||
static void M_DrawCenteredMenu(void);
|
||||
static void M_DrawAddons(void);
|
||||
static void M_DrawSkyRoom(void);
|
||||
static void M_DrawChecklist(void);
|
||||
static void M_DrawEmblemHints(void);
|
||||
|
@ -361,6 +376,7 @@ static boolean M_CancelConnect(void);
|
|||
#endif
|
||||
static boolean M_ExitPandorasBox(void);
|
||||
static boolean M_QuitMultiPlayerMenu(void);
|
||||
static void M_HandleAddons(INT32 choice);
|
||||
static void M_HandleSoundTest(INT32 choice);
|
||||
static void M_HandleImageDef(INT32 choice);
|
||||
static void M_HandleLoadSave(INT32 choice);
|
||||
|
@ -482,15 +498,16 @@ static consvar_t cv_dummystaff = {"dummystaff", "0", CV_HIDEN|CV_CALL, dummystaf
|
|||
// ---------
|
||||
static menuitem_t MainMenu[] =
|
||||
{
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Extras", &SR_UnlockChecklistDef, 84},
|
||||
{IT_CALL |IT_STRING, NULL, "1 Player", M_SinglePlayerMenu, 92},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Extras", &SR_UnlockChecklistDef, 76},
|
||||
{IT_CALL |IT_STRING, NULL, "1 Player", M_SinglePlayerMenu, 84},
|
||||
#ifdef NONET
|
||||
M_StartSplitServerMenu
|
||||
{IT_CALL |IT_STRING, NULL, "Splitscreen", M_StartSplitServerMenu,100},
|
||||
{IT_CALL |IT_STRING, NULL, "Splitscreen", M_StartSplitServerMenu, 92},
|
||||
#else
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Multiplayer", &MP_MainDef, 100},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Multiplayer", &MP_MainDef, 92},
|
||||
#endif
|
||||
{IT_CALL |IT_STRING, NULL, "Options", M_Options, 108},
|
||||
{IT_CALL |IT_STRING, NULL, "Options", M_Options, 100},
|
||||
{IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 108},
|
||||
{IT_CALL |IT_STRING, NULL, "Quit Game", M_QuitSRB2, 116},
|
||||
};
|
||||
|
||||
|
@ -500,9 +517,15 @@ typedef enum
|
|||
singleplr,
|
||||
multiplr,
|
||||
options,
|
||||
addons,
|
||||
quitdoom
|
||||
} main_e;
|
||||
|
||||
static menuitem_t MISC_AddonsMenu[] =
|
||||
{
|
||||
{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleAddons, 0}, // dummy menuitem for the control func
|
||||
};
|
||||
|
||||
// ---------------------------------
|
||||
// Pause Menu Mode Attacking Edition
|
||||
// ---------------------------------
|
||||
|
@ -525,8 +548,9 @@ typedef enum
|
|||
// ---------------------
|
||||
static menuitem_t MPauseMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
|
||||
{IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24},
|
||||
{IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8},
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
|
||||
{IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24},
|
||||
|
||||
{IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,40},
|
||||
{IT_CALL | IT_STRING, NULL, "P1 Setup...", M_SetupMultiPlayer, 48}, // splitscreen
|
||||
|
@ -549,7 +573,8 @@ static menuitem_t MPauseMenu[] =
|
|||
|
||||
typedef enum
|
||||
{
|
||||
mpause_scramble = 0,
|
||||
mpause_addons = 0,
|
||||
mpause_scramble,
|
||||
mpause_switchmap,
|
||||
|
||||
mpause_continue,
|
||||
|
@ -1065,10 +1090,11 @@ static menuitem_t OP_MainMenu[] =
|
|||
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Gameplay Options...", &OP_GameOptionsDef, 90},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Server Options...", &OP_ServerOptionsDef, 100},
|
||||
{IT_STRING|IT_CALL, NULL, "Add-on Options...", M_AddonsOptions, 110},
|
||||
|
||||
{IT_CALL|IT_STRING, NULL, "Tricks & Secrets (F1)", M_Manual, 120},
|
||||
{IT_CALL|IT_STRING, NULL, "Play Credits", M_Credits, 130},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Erase Data...", &OP_EraseDataDef, 140},
|
||||
{IT_CALL|IT_STRING, NULL, "Tricks & Secrets (F1)", M_Manual, 130},
|
||||
{IT_CALL|IT_STRING, NULL, "Play Credits", M_Credits, 140},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Erase Data...", &OP_EraseDataDef, 150},
|
||||
};
|
||||
|
||||
static menuitem_t OP_ControlsMenu[] =
|
||||
|
@ -1426,6 +1452,24 @@ static menuitem_t OP_EraseDataMenu[] =
|
|||
{IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", M_EraseData, 40},
|
||||
};
|
||||
|
||||
static menuitem_t OP_AddonsOptionsMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "Menu", NULL, 0},
|
||||
{IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 10},
|
||||
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 20},
|
||||
{IT_STRING|IT_CVAR, NULL, "Identify add-ons via", &cv_addons_md5, 48},
|
||||
{IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 58},
|
||||
|
||||
{IT_HEADER, NULL, "Search", NULL, 76},
|
||||
{IT_STRING|IT_CVAR, NULL, "Matching", &cv_addons_search_type, 86},
|
||||
{IT_STRING|IT_CVAR, NULL, "Case-sensitive", &cv_addons_search_case, 96},
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
op_addons_folder = 2,
|
||||
};
|
||||
|
||||
static menuitem_t OP_HUDOptionsMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_CVAR, NULL, "Show HUD (F3)", &cv_showhud, 10},
|
||||
|
@ -1572,6 +1616,18 @@ static menuitem_t OP_MonitorToggleMenu[] =
|
|||
// Main Menu and related
|
||||
menu_t MainDef = CENTERMENUSTYLE(NULL, MainMenu, NULL, 72);
|
||||
|
||||
menu_t MISC_AddonsDef =
|
||||
{
|
||||
NULL,
|
||||
sizeof (MISC_AddonsMenu)/sizeof (menuitem_t),
|
||||
&MainDef,
|
||||
MISC_AddonsMenu,
|
||||
M_DrawAddons,
|
||||
50, 28,
|
||||
0,
|
||||
NULL
|
||||
};
|
||||
|
||||
menu_t MAPauseDef = PAUSEMENUSTYLE(MAPauseMenu, 40, 72);
|
||||
menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72);
|
||||
menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72);
|
||||
|
@ -2026,7 +2082,8 @@ menu_t OP_OpenGLColorDef =
|
|||
#endif
|
||||
//menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30);
|
||||
menu_t OP_ScreenshotOptionsDef = DEFAULTMENUSTYLE("M_SCSHOT", OP_ScreenshotOptionsMenu, &OP_MainDef, 30, 30);
|
||||
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_MainDef, 60, 30);
|
||||
menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE("M_ADDONS", OP_AddonsOptionsMenu, &OP_MainDef, 30, 30);
|
||||
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_MainDef, 30, 30);
|
||||
|
||||
// ==========================================================================
|
||||
// CVAR ONCHANGE EVENTS GO HERE
|
||||
|
@ -2245,6 +2302,12 @@ void Moviemode_mode_Onchange(void)
|
|||
OP_ScreenshotOptionsMenu[i].status = IT_STRING|IT_CVAR;
|
||||
}
|
||||
|
||||
void Addons_option_Onchange(void)
|
||||
{
|
||||
OP_AddonsOptionsMenu[op_addons_folder].status =
|
||||
(cv_addons_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// END ORGANIZATION STUFF.
|
||||
// ==========================================================================
|
||||
|
@ -2732,6 +2795,7 @@ boolean M_Responder(event_t *ev)
|
|||
{
|
||||
// detach any keys associated with the game control
|
||||
G_ClearControlKeys(setupcontrols, currentMenu->menuitems[itemOn].alphaKey);
|
||||
S_StartSound(NULL, sfx_shldls);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2901,6 +2965,7 @@ void M_StartControlPanel(void)
|
|||
else // multiplayer
|
||||
{
|
||||
MPauseMenu[mpause_switchmap].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_addons].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_scramble].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_psetupsplit].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_psetupsplit2].status = IT_DISABLED;
|
||||
|
@ -2921,6 +2986,7 @@ void M_StartControlPanel(void)
|
|||
if ((server || IsPlayerAdmin(consoleplayer)))
|
||||
{
|
||||
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
|
||||
MPauseMenu[mpause_addons].status = IT_STRING | IT_CALL;
|
||||
if (G_GametypeHasTeams())
|
||||
MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU;
|
||||
}
|
||||
|
@ -4264,6 +4330,547 @@ static void M_HandleImageDef(INT32 choice)
|
|||
// MISC MAIN MENU OPTIONS
|
||||
// ======================
|
||||
|
||||
static void M_AddonsOptions(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
Addons_option_Onchange();
|
||||
|
||||
M_SetupNextMenu(&OP_AddonsOptionsDef);
|
||||
}
|
||||
|
||||
#define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!"
|
||||
#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make add-ons!"
|
||||
|
||||
static void M_Addons(INT32 choice)
|
||||
{
|
||||
const char *pathname = ".";
|
||||
|
||||
(void)choice;
|
||||
|
||||
#if 1
|
||||
if (cv_addons_option.value == 0)
|
||||
pathname = usehome ? srb2home : srb2path;
|
||||
else if (cv_addons_option.value == 1)
|
||||
pathname = srb2home;
|
||||
else if (cv_addons_option.value == 2)
|
||||
pathname = srb2path;
|
||||
else
|
||||
#endif
|
||||
if (cv_addons_option.value == 3 && *cv_addons_folder.string != '\0')
|
||||
pathname = cv_addons_folder.string;
|
||||
|
||||
strlcpy(menupath, pathname, 1024);
|
||||
menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1;
|
||||
|
||||
if (menupath[menupathindex[menudepthleft]-2] != PATHSEP[0])
|
||||
{
|
||||
menupath[menupathindex[menudepthleft]-1] = PATHSEP[0];
|
||||
menupath[menupathindex[menudepthleft]] = 0;
|
||||
}
|
||||
else
|
||||
--menupathindex[menudepthleft];
|
||||
|
||||
if (!preparefilemenu(false))
|
||||
{
|
||||
M_StartMessage(va("No files/folders found.\n\n%s\n\n(Press a key)\n", (recommendedflags == V_SKYMAP ? LOCATIONSTRING2 : LOCATIONSTRING1)),NULL,MM_NOTHING);
|
||||
return;
|
||||
}
|
||||
else
|
||||
dir_on[menudepthleft] = 0;
|
||||
|
||||
if (addonsp[0]) // never going to have some provided but not all, saves individually checking
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < NUM_EXT+5; i++)
|
||||
W_UnlockCachedPatch(addonsp[i]);
|
||||
}
|
||||
|
||||
addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_STATIC);
|
||||
addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_STATIC);
|
||||
addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_STATIC);
|
||||
addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC);
|
||||
addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC);
|
||||
addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC);
|
||||
addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_STATIC);
|
||||
//addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_STATIC);
|
||||
addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC);
|
||||
addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC);
|
||||
addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC);
|
||||
addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_STATIC);
|
||||
addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_STATIC);
|
||||
addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_STATIC);
|
||||
addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_STATIC);
|
||||
|
||||
MISC_AddonsDef.prevMenu = currentMenu;
|
||||
M_SetupNextMenu(&MISC_AddonsDef);
|
||||
}
|
||||
|
||||
#define width 4
|
||||
#define vpadding 27
|
||||
#define h (BASEVIDHEIGHT-(2*vpadding))
|
||||
#define NUMCOLOURS 8 // when toast's coding it's british english hacker fucker
|
||||
static void M_DrawTemperature(INT32 x, fixed_t t)
|
||||
{
|
||||
INT32 y;
|
||||
|
||||
// bounds check
|
||||
if (t > FRACUNIT)
|
||||
t = FRACUNIT;
|
||||
/*else if (t < 0) -- not needed
|
||||
t = 0;*/
|
||||
|
||||
// scale
|
||||
if (t > 1)
|
||||
t = (FixedMul(h<<FRACBITS, t)>>FRACBITS);
|
||||
|
||||
// border
|
||||
V_DrawFill(x - 1, vpadding, 1, h, 120);
|
||||
V_DrawFill(x + width, vpadding, 1, h, 120);
|
||||
V_DrawFill(x - 1, vpadding-1, width+2, 1, 120);
|
||||
V_DrawFill(x - 1, vpadding+h, width+2, 1, 120);
|
||||
|
||||
// bar itself
|
||||
y = h;
|
||||
if (t)
|
||||
for (t = h - t; y > 0; y--)
|
||||
{
|
||||
UINT8 colours[NUMCOLOURS] = {135, 133, 92, 77, 114, 178, 161, 162};
|
||||
UINT8 c;
|
||||
if (y <= t) break;
|
||||
if (y+vpadding >= BASEVIDHEIGHT/2)
|
||||
c = 185;
|
||||
else
|
||||
c = colours[(NUMCOLOURS*(y-1))/(h/2)];
|
||||
V_DrawFill(x, y-1 + vpadding, width, 1, c);
|
||||
}
|
||||
|
||||
// fill the rest of the backing
|
||||
if (y)
|
||||
V_DrawFill(x, vpadding, width, y, 30);
|
||||
}
|
||||
#undef width
|
||||
#undef vpadding
|
||||
#undef h
|
||||
#undef NUMCOLOURS
|
||||
|
||||
static char *M_AddonsHeaderPath(void)
|
||||
{
|
||||
UINT32 len;
|
||||
static char header[1024];
|
||||
|
||||
strlcpy(header, va("%s folder%s", cv_addons_option.string, menupath+menupathindex[menudepth-1]-1), 1024);
|
||||
len = strlen(header);
|
||||
if (len > 34)
|
||||
{
|
||||
len = len-34;
|
||||
header[len] = header[len+1] = header[len+2] = '.';
|
||||
}
|
||||
else
|
||||
len = 0;
|
||||
|
||||
return header+len;
|
||||
}
|
||||
|
||||
#define UNEXIST S_StartSound(NULL, sfx_lose);\
|
||||
M_SetupNextMenu(MISC_AddonsDef.prevMenu);\
|
||||
M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING)
|
||||
|
||||
#define CLEARNAME Z_Free(refreshdirname);\
|
||||
refreshdirname = NULL
|
||||
|
||||
static void M_AddonsClearName(INT32 choice)
|
||||
{
|
||||
CLEARNAME;
|
||||
M_StopMessage(choice);
|
||||
}
|
||||
|
||||
// returns whether to do message draw
|
||||
static boolean M_AddonsRefresh(void)
|
||||
{
|
||||
if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true))
|
||||
{
|
||||
UNEXIST;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (refreshdirmenu & REFRESHDIR_ADDFILE)
|
||||
{
|
||||
char *message = NULL;
|
||||
|
||||
if (refreshdirmenu & REFRESHDIR_NOTLOADED)
|
||||
{
|
||||
S_StartSound(NULL, sfx_lose);
|
||||
if (refreshdirmenu & REFRESHDIR_MAX)
|
||||
message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||
else
|
||||
message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||
}
|
||||
else if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR))
|
||||
{
|
||||
S_StartSound(NULL, sfx_skid);
|
||||
message = va("%c%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings"));
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
M_StartMessage(message,M_AddonsClearName,MM_EVENTHANDLER);
|
||||
return true;
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_strpst);
|
||||
CLEARNAME;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef FIXUPO0
|
||||
#pragma GCC optimize ("0")
|
||||
#endif
|
||||
|
||||
static void M_DrawAddons(void)
|
||||
{
|
||||
INT32 x, y;
|
||||
ssize_t i, m;
|
||||
const UINT8 *flashcol = NULL;
|
||||
UINT8 hilicol;
|
||||
|
||||
// hack - need to refresh at end of frame to handle addfile...
|
||||
if (refreshdirmenu & M_AddonsRefresh())
|
||||
{
|
||||
M_DrawMessageMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Playing())
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 5, warningflags, "Adding files mid-game may cause problems.");
|
||||
else
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 5, 0, (recommendedflags == V_SKYMAP ? LOCATIONSTRING2 : LOCATIONSTRING1));
|
||||
|
||||
if (numwadfiles <= mainwads+1)
|
||||
y = 0;
|
||||
else if (numwadfiles >= MAX_WADFILES)
|
||||
y = FRACUNIT;
|
||||
else
|
||||
{
|
||||
x = FixedDiv(((ssize_t)(numwadfiles) - (ssize_t)(mainwads+1))<<FRACBITS, ((ssize_t)MAX_WADFILES - (ssize_t)(mainwads+1))<<FRACBITS);
|
||||
y = FixedDiv((((ssize_t)packetsizetally-(ssize_t)mainwadstally)<<FRACBITS), ((((ssize_t)MAXFILENEEDED*sizeof(UINT8)-(ssize_t)mainwadstally)-(5+22))<<FRACBITS)); // 5+22 = (a.ext + checksum length) is minimum addition to packet size tally
|
||||
if (x > y)
|
||||
y = x;
|
||||
if (y > FRACUNIT) // happens because of how we're shrinkin' it a little
|
||||
y = FRACUNIT;
|
||||
}
|
||||
|
||||
M_DrawTemperature(BASEVIDWIDTH - 19 - 5, y);
|
||||
|
||||
// DRAW MENU
|
||||
x = currentMenu->x;
|
||||
y = currentMenu->y + 1;
|
||||
|
||||
hilicol = V_GetStringColormap(highlightflags)[120];
|
||||
|
||||
V_DrawString(x-21, (y - 16) + (lsheadingheight - 12), highlightflags|V_ALLOWLOWERCASE, M_AddonsHeaderPath());
|
||||
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 3), MAXSTRINGLENGTH*8+6, 1, hilicol);
|
||||
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), MAXSTRINGLENGTH*8+6, 1, 30);
|
||||
|
||||
m = (BASEVIDHEIGHT - currentMenu->y + 2) - (y - 1);
|
||||
V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, m, 239);
|
||||
|
||||
// scrollbar!
|
||||
if (sizedirmenu <= (2*numaddonsshown + 1))
|
||||
i = 0;
|
||||
else
|
||||
{
|
||||
ssize_t q = m;
|
||||
m = ((2*numaddonsshown + 1) * m)/sizedirmenu;
|
||||
if (dir_on[menudepthleft] <= numaddonsshown) // all the way up
|
||||
i = 0;
|
||||
else if (sizedirmenu <= (dir_on[menudepthleft] + numaddonsshown + 1)) // all the way down
|
||||
i = q-m;
|
||||
else
|
||||
i = ((dir_on[menudepthleft] - numaddonsshown) * (q-m))/(sizedirmenu - (2*numaddonsshown + 1));
|
||||
}
|
||||
|
||||
V_DrawFill(x + MAXSTRINGLENGTH*8+5 - 21, (y - 1) + i, 1, m, hilicol);
|
||||
|
||||
// get bottom...
|
||||
m = dir_on[menudepthleft] + numaddonsshown + 1;
|
||||
if (m > (ssize_t)sizedirmenu)
|
||||
m = sizedirmenu;
|
||||
|
||||
// then top...
|
||||
i = m - (2*numaddonsshown + 1);
|
||||
|
||||
// then adjust!
|
||||
if (i < 0)
|
||||
{
|
||||
if ((m -= i) > (ssize_t)sizedirmenu)
|
||||
m = sizedirmenu;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (i != 0)
|
||||
V_DrawString(19, y+4 - (skullAnimCounter/5), highlightflags, "\x1A");
|
||||
|
||||
if (skullAnimCounter < 4)
|
||||
flashcol = V_GetStringColormap(highlightflags);
|
||||
|
||||
for (; i < m; i++)
|
||||
{
|
||||
UINT32 flags = V_ALLOWLOWERCASE;
|
||||
if (y > BASEVIDHEIGHT) break;
|
||||
if (dirmenu[i])
|
||||
#define type (UINT8)(dirmenu[i][DIR_TYPE])
|
||||
{
|
||||
if (type & EXT_LOADED)
|
||||
{
|
||||
flags |= V_TRANSLUCENT;
|
||||
V_DrawSmallScaledPatch(x-(16+4), y, V_TRANSLUCENT, addonsp[(type & ~EXT_LOADED)]);
|
||||
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+2]);
|
||||
}
|
||||
else
|
||||
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[(type & ~EXT_LOADED)]);
|
||||
|
||||
if ((size_t)i == dir_on[menudepthleft])
|
||||
{
|
||||
V_DrawFixedPatch((x-(16+4))<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, 0, addonsp[NUM_EXT+1], flashcol);
|
||||
flags = V_ALLOWLOWERCASE|highlightflags;
|
||||
}
|
||||
|
||||
#define charsonside 14
|
||||
if (dirmenu[i][DIR_LEN] > (charsonside*2 + 3))
|
||||
V_DrawString(x, y+4, flags, va("%.*s...%s", charsonside, dirmenu[i]+DIR_STRING, dirmenu[i]+DIR_STRING+dirmenu[i][DIR_LEN]-(charsonside+1)));
|
||||
#undef charsonside
|
||||
else
|
||||
V_DrawString(x, y+4, flags, dirmenu[i]+DIR_STRING);
|
||||
}
|
||||
#undef type
|
||||
y += 16;
|
||||
}
|
||||
|
||||
if (m != (ssize_t)sizedirmenu)
|
||||
V_DrawString(19, y-12 + (skullAnimCounter/5), highlightflags, "\x1B");
|
||||
|
||||
y = BASEVIDHEIGHT - currentMenu->y + 1;
|
||||
|
||||
M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1);
|
||||
if (menusearch[0])
|
||||
V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1);
|
||||
else
|
||||
V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE|V_TRANSLUCENT, "Type to search...");
|
||||
if (skullAnimCounter < 4)
|
||||
V_DrawCharacter(x - 18 + V_StringWidth(menusearch+1, 0), y + 8,
|
||||
'_' | 0x80, false);
|
||||
|
||||
x -= (21 + 5 + 16);
|
||||
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+3]);
|
||||
|
||||
x = BASEVIDWIDTH - x - 16;
|
||||
V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
|
||||
|
||||
if (modifiedgame)
|
||||
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+2]);
|
||||
}
|
||||
|
||||
#ifdef FIXUPO0
|
||||
#pragma GCC reset_options
|
||||
#endif
|
||||
|
||||
static void M_AddonExec(INT32 ch)
|
||||
{
|
||||
if (ch != 'y' && ch != KEY_ENTER)
|
||||
return;
|
||||
|
||||
S_StartSound(NULL, sfx_zoom);
|
||||
COM_BufAddText(va("exec \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||
}
|
||||
|
||||
#define len menusearch[0]
|
||||
static boolean M_ChangeStringAddons(INT32 choice)
|
||||
{
|
||||
if (shiftdown && choice >= 32 && choice <= 127)
|
||||
choice = shiftxform[choice];
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_DEL:
|
||||
if (len)
|
||||
{
|
||||
len = menusearch[1] = 0;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case KEY_BACKSPACE:
|
||||
if (len)
|
||||
{
|
||||
menusearch[1+--len] = 0;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (choice >= 32 && choice <= 127)
|
||||
{
|
||||
if (len < MAXSTRINGLENGTH - 1)
|
||||
{
|
||||
menusearch[1+len++] = (char)choice;
|
||||
menusearch[1+len] = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#undef len
|
||||
|
||||
static void M_HandleAddons(INT32 choice)
|
||||
{
|
||||
boolean exitmenu = false; // exit to previous menu
|
||||
|
||||
if (M_ChangeStringAddons(choice))
|
||||
{
|
||||
char *tempname = NULL;
|
||||
if (dirmenu && dirmenu[dir_on[menudepthleft]])
|
||||
tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL
|
||||
#if 0 // much slower
|
||||
if (!preparefilemenu(true))
|
||||
{
|
||||
UNEXIST;
|
||||
return;
|
||||
}
|
||||
#else // streamlined
|
||||
searchfilemenu(tempname);
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_DOWNARROW:
|
||||
if (dir_on[menudepthleft] < sizedirmenu-1)
|
||||
dir_on[menudepthleft]++;
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
break;
|
||||
case KEY_UPARROW:
|
||||
if (dir_on[menudepthleft])
|
||||
dir_on[menudepthleft]--;
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
break;
|
||||
case KEY_PGDN:
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = numaddonsshown; i && (dir_on[menudepthleft] < sizedirmenu-1); i--)
|
||||
dir_on[menudepthleft]++;
|
||||
}
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
break;
|
||||
case KEY_PGUP:
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = numaddonsshown; i && (dir_on[menudepthleft]); i--)
|
||||
dir_on[menudepthleft]--;
|
||||
}
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
break;
|
||||
case KEY_ENTER:
|
||||
{
|
||||
boolean refresh = true;
|
||||
if (!dirmenu[dir_on[menudepthleft]])
|
||||
S_StartSound(NULL, sfx_lose);
|
||||
else
|
||||
{
|
||||
switch (dirmenu[dir_on[menudepthleft]][DIR_TYPE])
|
||||
{
|
||||
case EXT_FOLDER:
|
||||
strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+DIR_STRING);
|
||||
if (menudepthleft)
|
||||
{
|
||||
menupathindex[--menudepthleft] = strlen(menupath);
|
||||
menupath[menupathindex[menudepthleft]] = 0;
|
||||
|
||||
if (!preparefilemenu(false))
|
||||
{
|
||||
S_StartSound(NULL, sfx_skid);
|
||||
M_StartMessage(va("%c%s\x80\nThis folder is empty.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||
menupath[menupathindex[++menudepthleft]] = 0;
|
||||
|
||||
if (!preparefilemenu(true))
|
||||
{
|
||||
UNEXIST;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
dir_on[menudepthleft] = 1;
|
||||
}
|
||||
refresh = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound(NULL, sfx_lose);
|
||||
M_StartMessage(va("%c%s\x80\nThis folder is too deep to navigate to!\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||
menupath[menupathindex[menudepthleft]] = 0;
|
||||
}
|
||||
break;
|
||||
case EXT_UP:
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
menupath[menupathindex[++menudepthleft]] = 0;
|
||||
if (!preparefilemenu(false))
|
||||
{
|
||||
UNEXIST;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case EXT_TXT:
|
||||
M_StartMessage(va("%c%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),M_AddonExec,MM_YESNO);
|
||||
break;
|
||||
case EXT_CFG:
|
||||
M_AddonExec(KEY_ENTER);
|
||||
break;
|
||||
case EXT_LUA:
|
||||
#ifndef HAVE_BLUA
|
||||
S_StartSound(NULL, sfx_lose);
|
||||
M_StartMessage(va("%c%s\x80\nThis copy of SRB2 was compiled\nwithout support for .lua files.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
|
||||
break;
|
||||
#endif
|
||||
// else intentional fallthrough
|
||||
case EXT_SOC:
|
||||
case EXT_WAD:
|
||||
case EXT_KART:
|
||||
//case EXT_PK3:
|
||||
COM_BufAddText(va("addfile \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||
break;
|
||||
default:
|
||||
S_StartSound(NULL, sfx_lose);
|
||||
}
|
||||
}
|
||||
if (refresh)
|
||||
refreshdirmenu |= REFRESHDIR_NORMAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_ESCAPE:
|
||||
exitmenu = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (exitmenu)
|
||||
{
|
||||
closefilemenu(true);
|
||||
|
||||
// Secret menu!
|
||||
//MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
|
||||
|
||||
if (currentMenu->prevMenu)
|
||||
M_SetupNextMenu(currentMenu->prevMenu);
|
||||
else
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
}
|
||||
|
||||
static void M_PandorasBox(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
@ -4366,8 +4973,8 @@ static void M_Options(INT32 choice)
|
|||
OP_MainMenu[5].status = OP_MainMenu[6].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
||||
|
||||
// if the player is playing _at all_, disable the erase data & credits options
|
||||
OP_MainMenu[8].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL);
|
||||
OP_MainMenu[9].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
||||
OP_MainMenu[9].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL);
|
||||
OP_MainMenu[10].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
||||
|
||||
OP_GameOptionsMenu[3].status =
|
||||
(M_SecretUnlocked(SECRET_ENCORE)) ? (IT_CVAR|IT_STRING) : IT_SECRET; // cv_kartencore
|
||||
|
@ -8067,23 +8674,22 @@ static void M_ChangecontrolResponse(event_t *ev)
|
|||
setupcontrols[control][found] = ch-KEY_4JOY1+KEY_DBL4JOY1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if change key1 or key2, or replace the two by the new
|
||||
found = 0;
|
||||
if (setupcontrols[control][0] == KEY_NULL)
|
||||
found++;
|
||||
if (setupcontrols[control][1] == KEY_NULL)
|
||||
found++;
|
||||
if (found == 2)
|
||||
{
|
||||
found = 0;
|
||||
setupcontrols[control][1] = KEY_NULL; //replace key 1,clear key2
|
||||
}
|
||||
G_CheckDoubleUsage(ch);
|
||||
setupcontrols[control][found] = ch;
|
||||
}
|
||||
|
||||
{
|
||||
// check if change key1 or key2, or shuffle them along in a queue
|
||||
found = 0;
|
||||
if (setupcontrols[control][0] != KEY_NULL)
|
||||
{
|
||||
found++;
|
||||
if (setupcontrols[control][1] != KEY_NULL)
|
||||
setupcontrols[control][0] = setupcontrols[control][1];
|
||||
}
|
||||
G_CheckDoubleUsage(ch);
|
||||
setupcontrols[control][found] = ch;
|
||||
}
|
||||
S_StartSound(NULL, sfx_strpst);
|
||||
}
|
||||
else
|
||||
S_StartSound(NULL, sfx_skid);
|
||||
|
||||
M_StopMessage(0);
|
||||
}
|
||||
|
|
|
@ -124,6 +124,8 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
|||
#define IT_HEADER (IT_SPACE +IT_HEADERTEXT)
|
||||
#define IT_SECRET (IT_SPACE +IT_QUESTIONMARKS)
|
||||
|
||||
#define MAXSTRINGLENGTH 32
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct menu_s *submenu; // IT_SUBMENU
|
||||
|
@ -223,6 +225,9 @@ void M_CheatActivationResponder(INT32 ch);
|
|||
void Moviemode_mode_Onchange(void);
|
||||
void Screenshot_option_Onchange(void);
|
||||
|
||||
// Addons menu updating
|
||||
void Addons_option_Onchange(void);
|
||||
|
||||
// These defines make it a little easier to make menus
|
||||
#define DEFAULTMENUSTYLE(header, source, prev, x, y)\
|
||||
{\
|
||||
|
|
|
@ -192,6 +192,7 @@ void A_JawzChase(mobj_t *actor); // SRB2kart
|
|||
void A_JawzExplode(mobj_t *actor); // SRB2kart
|
||||
void A_MineExplode(mobj_t *actor); // SRB2kart
|
||||
void A_BallhogExplode(mobj_t *actor); // SRB2kart
|
||||
void A_LightningFollowPlayer(mobj_t *actor); // SRB2kart
|
||||
void A_OrbitNights(mobj_t *actor);
|
||||
void A_GhostMe(mobj_t *actor);
|
||||
void A_SetObjectState(mobj_t *actor);
|
||||
|
@ -8312,6 +8313,34 @@ void A_BallhogExplode(mobj_t *actor)
|
|||
S_StartSound(mo2, actor->info->deathsound);
|
||||
return;
|
||||
}
|
||||
|
||||
// A_LightningFollowPlayer:
|
||||
// Dumb simple function that gives a mobj its target's momentums without updating its angle.
|
||||
void A_LightningFollowPlayer(mobj_t *actor)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_LightningFollowPlayer", actor))
|
||||
return;
|
||||
#endif
|
||||
fixed_t sx, sy;
|
||||
if (actor->target)
|
||||
{
|
||||
if (actor->extravalue1) // Make the radius also follow the player somewhat accuratly
|
||||
{
|
||||
sx = actor->target->x + FixedMul((actor->target->scale*actor->extravalue1), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT));
|
||||
sy = actor->target->y + FixedMul((actor->target->scale*actor->extravalue1), FINESINE((actor->angle)>>ANGLETOFINESHIFT));
|
||||
P_TeleportMove(actor, sx, sy, actor->target->z);
|
||||
}
|
||||
else // else just teleport to player directly
|
||||
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z);
|
||||
|
||||
actor->momx = actor->target->momx;
|
||||
actor->momy = actor->target->momy;
|
||||
actor->momz = actor->target->momz; // Give momentum since we don't teleport to our player literally every frame.
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//}
|
||||
|
||||
// Function: A_OrbitNights
|
||||
|
|
|
@ -181,13 +181,13 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
|
|||
{
|
||||
// Item-specific timer going off
|
||||
if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer]
|
||||
|| player->kartstuff[k_growshrinktimer] != 0 || player->kartstuff[k_rocketsneakertimer]
|
||||
|| player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_rocketsneakertimer]
|
||||
|| player->kartstuff[k_eggmanexplode])
|
||||
return false;
|
||||
|
||||
// Item slot already taken up
|
||||
if (player->kartstuff[k_itemroulette]
|
||||
|| player->kartstuff[k_itemamount]
|
||||
|| (weapon != 3 && player->kartstuff[k_itemamount])
|
||||
|| player->kartstuff[k_itemheld])
|
||||
return false;
|
||||
}
|
||||
|
@ -429,6 +429,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
// We now identify by object type, not sprite! Tails 04-11-2001
|
||||
switch (special->type)
|
||||
{
|
||||
case MT_FLOATINGITEM: // SRB2kart
|
||||
if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold))
|
||||
return;
|
||||
|
||||
if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0)
|
||||
return;
|
||||
|
||||
player->kartstuff[k_itemtype] = special->threshold;
|
||||
player->kartstuff[k_itemamount] += special->movecount;
|
||||
if (player->kartstuff[k_itemamount] > 255)
|
||||
player->kartstuff[k_itemamount] = 255;
|
||||
|
||||
S_StartSound(special, special->info->deathsound);
|
||||
|
||||
P_SetTarget(&special->tracer, toucher);
|
||||
special->flags2 |= MF2_NIGHTSPULL;
|
||||
special->destscale = mapheaderinfo[gamemap-1]->mobj_scale>>4;
|
||||
special->scalespeed <<= 1;
|
||||
|
||||
special->flags &= ~MF_SPECIAL;
|
||||
return;
|
||||
case MT_RANDOMITEM: // SRB2kart
|
||||
if (!P_CanPickupItem(player, 1))
|
||||
return;
|
||||
|
@ -469,9 +490,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
S_StartSound(poof, special->info->deathsound);
|
||||
|
||||
K_StripItems(player);
|
||||
if (player->kartstuff[k_itemroulette] <= 0)
|
||||
player->kartstuff[k_itemroulette] = 1;
|
||||
K_DropItems(player); //K_StripItems(player);
|
||||
K_StripOther(player);
|
||||
player->kartstuff[k_itemroulette] = 1;
|
||||
player->kartstuff[k_roulettetype] = 2;
|
||||
if (special->target && special->target->player
|
||||
&& (G_RaceGametype() || special->target->player->kartstuff[k_bumper] > 0))
|
||||
|
@ -2625,6 +2646,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
|||
}
|
||||
}
|
||||
|
||||
if ((target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD) && !(target->flags2 & MF2_AMBUSH))
|
||||
{
|
||||
target->z += P_MobjFlip(target)*20*target->scale;
|
||||
}
|
||||
|
||||
if (target->type == MT_SPIKE && inflictor && target->info->deathstate != S_NULL)
|
||||
{
|
||||
const fixed_t x=target->x,y=target->y,z=target->z;
|
||||
|
@ -3334,6 +3360,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
player->mo->destscale = 6*player->mo->destscale/8;
|
||||
|
||||
// Wipeout
|
||||
K_DropItems(player);
|
||||
K_SpinPlayer(player, source, 1, false);
|
||||
damage = player->mo->health - 1;
|
||||
P_RingDamage(player, inflictor, source, damage);
|
||||
|
@ -3345,7 +3372,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
quake.time = 5;
|
||||
}
|
||||
|
||||
K_StripItems(player);
|
||||
player->kartstuff[k_growshrinktimer] -= (200+(40*(16-player->kartstuff[k_position])));
|
||||
}
|
||||
// Grow? Let's take that away.
|
||||
|
|
|
@ -497,7 +497,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)))
|
||||
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)) || (thing->flags & MF_NOCLIPTHING))
|
||||
return true;
|
||||
|
||||
// Don't collide with your buddies while NiGHTS-flying.
|
||||
|
|
326
src/p_mobj.c
326
src/p_mobj.c
|
@ -48,6 +48,7 @@ actioncache_t actioncachehead;
|
|||
|
||||
static mobj_t *overlaycap = NULL;
|
||||
static mobj_t *shadowcap = NULL;
|
||||
mobj_t *waypointcap = NULL;
|
||||
|
||||
void P_InitCachedActions(void)
|
||||
{
|
||||
|
@ -6011,7 +6012,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
|
|||
return;
|
||||
|
||||
// change angle
|
||||
source->angle = R_PointToAngle2(source->x, source->y, tx, ty);
|
||||
//source->angle = R_PointToAngle2(source->x, source->y, tx, ty);
|
||||
|
||||
// change slope
|
||||
dist = P_AproxDistance(P_AproxDistance(tx - source->x, ty - source->y), tz - source->z);
|
||||
|
@ -6020,7 +6021,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
|
|||
dist = 1;
|
||||
|
||||
if (nightsgrab)
|
||||
speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(8*FRACUNIT, source->scale);
|
||||
speedmul = P_AproxDistance(dest->momx, dest->momy) + source->scale;
|
||||
else
|
||||
speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(source->info->speed, source->scale);
|
||||
|
||||
|
@ -6284,16 +6285,18 @@ static void P_RemoveOverlay(mobj_t *thing)
|
|||
|
||||
void P_RunShadows(void)
|
||||
{
|
||||
mobj_t *mobj;
|
||||
mobj_t *next;
|
||||
mobj_t *mobj, *next, *dest;
|
||||
|
||||
for (mobj = shadowcap; mobj; mobj = next)
|
||||
{
|
||||
next = mobj->hnext;
|
||||
P_SetTarget(&mobj->hnext, NULL);
|
||||
|
||||
if (!mobj->target)
|
||||
if (!mobj->target || P_MobjWasRemoved(mobj->target))
|
||||
{
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
continue; // shouldn't you already be dead?
|
||||
}
|
||||
|
||||
if ((mobj->target->flags2 & MF2_DONTDRAW)
|
||||
|| (((mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z+mobj->target->height > mobj->target->ceilingz)
|
||||
|
@ -6330,7 +6333,12 @@ void P_RunShadows(void)
|
|||
// First scale to the same radius
|
||||
P_SetScale(mobj, FixedDiv(mobj->target->radius, mobj->info->radius));
|
||||
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
dest = mobj->target;
|
||||
|
||||
if (dest->type == MT_THUNDERSHIELD)
|
||||
dest = dest->target;
|
||||
|
||||
P_TeleportMove(mobj, dest->x, dest->y, mobj->target->z);
|
||||
|
||||
if (((mobj->eflags & MFE_VERTICALFLIP) && (mobj->ceilingz > mobj->z+mobj->height))
|
||||
|| (!(mobj->eflags & MFE_VERTICALFLIP) && (mobj->floorz < mobj->z)))
|
||||
|
@ -6348,7 +6356,7 @@ void P_RunShadows(void)
|
|||
P_SetScale(mobj, FixedDiv(mobj->scale, max(FRACUNIT, ((mobj->target->z-mobj->z)/200)+FRACUNIT)));
|
||||
|
||||
// Check new position to see if you should still be on that ledge
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->z);
|
||||
P_TeleportMove(mobj, dest->x, dest->y, mobj->z);
|
||||
|
||||
mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : mobj->floorz);
|
||||
|
||||
|
@ -6356,6 +6364,9 @@ void P_RunShadows(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mobj->target->type == MT_FLOATINGITEM)
|
||||
P_SetScale(mobj, mobj->scale/2);
|
||||
}
|
||||
P_SetTarget(&shadowcap, NULL);
|
||||
}
|
||||
|
@ -6631,7 +6642,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
/*if (mobj->health > 0 && mobj->target && mobj->target->player
|
||||
&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
|
||||
{
|
||||
// Was this so hard? -- Handled this with K_UpdateHnextList and K_ClearHnextList instead of thinking it away...
|
||||
// Was this so hard? -- Handled this with K_UpdateHnextList instead of thinking it away...
|
||||
if ((mobj->type == MT_ORBINAUT_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_ORBINAUT)
|
||||
|| (mobj->type == MT_JAWZ_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_JAWZ)
|
||||
|| (mobj->movedir > 0 && ((UINT16)mobj->target->player->kartstuff[k_itemamount] < mobj->movedir))
|
||||
|
@ -6815,14 +6826,16 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->x = mobj->target->x;
|
||||
mobj->y = mobj->target->y;
|
||||
|
||||
mobj->angle = R_PointToAngle(mobj->x, mobj->y) + ANGLE_90; // literally only happened because i wanted to ^L^R the SPR_ITEM's
|
||||
|
||||
if (!(mobj->target->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
mobj->z = mobj->target->z + P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT;
|
||||
mobj->z = mobj->target->z + P_GetPlayerHeight(mobj->target->player)+(16+11)*mapheaderinfo[gamemap-1]->mobj_scale;
|
||||
mobj->eflags &= ~MFE_VERTICALFLIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->z = mobj->target->z - P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT;
|
||||
mobj->z = mobj->target->z - P_GetPlayerHeight(mobj->target->player)+(16+11)*mapheaderinfo[gamemap-1]->mobj_scale;
|
||||
mobj->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
P_SetThingPosition(mobj);
|
||||
|
@ -6838,7 +6851,8 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->tracer = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY);
|
||||
P_SetTarget(&mobj->tracer->target, mobj);
|
||||
P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM);
|
||||
P_SetScale(mobj->tracer, mobj->scale);
|
||||
P_SetMobjState(mobj->tracer, S_ITEMICON); // null sprite and frame to be overwritten later
|
||||
P_SetScale(mobj->tracer, (mobj->tracer->destscale = mobj->scale));
|
||||
}
|
||||
|
||||
if (!(mobj->flags2 & MF2_DONTDRAW))
|
||||
|
@ -6939,7 +6953,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
else
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW);
|
||||
P_SetMobjState(mobj->tracer, S_INVISIBLE);
|
||||
P_SetMobjState(mobj->tracer, S_ITEMICON); // null sprite and frame to be overwritten later
|
||||
}
|
||||
|
||||
mobj->tracer->destscale = scale;
|
||||
|
@ -7009,12 +7023,12 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
|
||||
if (!(mobj->target->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
mobj->z = mobj->target->z + (P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT+(64*mobj->scale));
|
||||
mobj->z = mobj->target->z + (P_GetPlayerHeight(mobj->target->player)+16*mapheaderinfo[gamemap-1]->mobj_scale+(64*mobj->scale));
|
||||
mobj->eflags &= ~MFE_VERTICALFLIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->z = mobj->target->z - (P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT+(64*mobj->scale));
|
||||
mobj->z = mobj->target->z - (P_GetPlayerHeight(mobj->target->player)+16*mapheaderinfo[gamemap-1]->mobj_scale+(64*mobj->scale));
|
||||
mobj->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
P_SetThingPosition(mobj);
|
||||
|
@ -7919,46 +7933,120 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->threshold = 0;
|
||||
}
|
||||
break;
|
||||
case MT_ORBINAUT:
|
||||
case MT_FLOATINGITEM:
|
||||
{
|
||||
sector_t *sec2;
|
||||
fixed_t finalspeed = mobj->info->speed;
|
||||
|
||||
P_SpawnGhostMobj(mobj);
|
||||
|
||||
if (gamespeed == 0)
|
||||
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
|
||||
else if (gamespeed == 2)
|
||||
finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4);
|
||||
|
||||
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
|
||||
if (mobj->health <= 5)
|
||||
if (mobj->flags & MF_NOCLIPTHING)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 5; i >= mobj->health; i--)
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
|
||||
mobj->momx = 1;
|
||||
mobj->momy = 0;
|
||||
mobj->flags &= ~MF_NOCLIPTHING;
|
||||
mobj->flags |= MF_NOGRAVITY;
|
||||
}
|
||||
finalspeed = FixedMul(finalspeed, mapheaderinfo[gamemap-1]->mobj_scale);
|
||||
P_InstaThrust(mobj, mobj->angle, finalspeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
finalspeed = FixedMul(finalspeed, mapheaderinfo[gamemap-1]->mobj_scale);
|
||||
P_InstaThrust(mobj, mobj->angle, finalspeed);
|
||||
mobj->angle += 2*ANG2;
|
||||
if (mobj->flags2 & MF2_NIGHTSPULL)
|
||||
{
|
||||
if (!mobj->tracer || !mobj->tracer->health
|
||||
|| mobj->scale <= mapheaderinfo[gamemap-1]->mobj_scale>>4)
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
P_Attract(mobj, mobj->tracer, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t adj = FixedMul(FRACUNIT - FINECOSINE((mobj->movedir>>ANGLETOFINESHIFT) & FINEMASK), (mapheaderinfo[gamemap-1]->mobj_scale<<3));
|
||||
mobj->movedir += 2*ANG2;
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
mobj->z = mobj->ceilingz - mobj->height - adj;
|
||||
else
|
||||
mobj->z = mobj->floorz + adj;
|
||||
}
|
||||
}
|
||||
|
||||
sec2 = P_ThingOnSpecial3DFloor(mobj);
|
||||
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|
||||
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
|
||||
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
|
||||
K_DoPogoSpring(mobj, 0, false);
|
||||
switch (mobj->threshold)
|
||||
{
|
||||
case KITEM_ORBINAUT:
|
||||
mobj->sprite = SPR_ITMO;
|
||||
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(min(mobj->movecount-1, 3));
|
||||
break;
|
||||
case KITEM_INVINCIBILITY:
|
||||
mobj->sprite = SPR_ITMI;
|
||||
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|((leveltime % (7*3)) / 3);
|
||||
break;
|
||||
case KITEM_SAD:
|
||||
mobj->sprite = SPR_ITEM;
|
||||
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE;
|
||||
break;
|
||||
default:
|
||||
mobj->sprite = SPR_ITEM;
|
||||
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(mobj->threshold);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MT_ORBINAUT:
|
||||
{
|
||||
boolean grounded = P_IsObjectOnGround(mobj);
|
||||
if (mobj->flags2 & MF2_AMBUSH)
|
||||
{
|
||||
if (grounded && (mobj->flags & MF_NOCLIPTHING))
|
||||
{
|
||||
mobj->momx = 1;
|
||||
mobj->momy = 0;
|
||||
mobj->frame = 3;
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
mobj->flags &= ~MF_NOCLIPTHING;
|
||||
}
|
||||
else if (mobj->movecount)
|
||||
mobj->movecount--;
|
||||
else if (mobj->frame < 3)
|
||||
{
|
||||
mobj->movecount = 2;
|
||||
mobj->frame++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t finalspeed = mobj->info->speed;
|
||||
|
||||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
P_SpawnGhostMobj(mobj);
|
||||
|
||||
if (leveltime % 6 == 0)
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
if (gamespeed == 0)
|
||||
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
|
||||
else if (gamespeed == 2)
|
||||
finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4);
|
||||
|
||||
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
|
||||
if (mobj->health <= 5)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 5; i >= mobj->health; i--)
|
||||
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
|
||||
}
|
||||
finalspeed = FixedMul(finalspeed, mapheaderinfo[gamemap-1]->mobj_scale);
|
||||
P_InstaThrust(mobj, mobj->angle, finalspeed);
|
||||
|
||||
if (grounded)
|
||||
{
|
||||
sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj);
|
||||
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|
||||
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
|
||||
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
|
||||
K_DoPogoSpring(mobj, 0, false);
|
||||
}
|
||||
|
||||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
|
||||
if (leveltime % 6 == 0)
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MT_JAWZ:
|
||||
|
@ -8031,23 +8119,38 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
case MT_JAWZ_DUD:
|
||||
{
|
||||
sector_t *sec2;
|
||||
boolean grounded = P_IsObjectOnGround(mobj);
|
||||
if (mobj->flags2 & MF2_AMBUSH)
|
||||
{
|
||||
if (grounded && (mobj->flags & MF_NOCLIPTHING))
|
||||
{
|
||||
mobj->momx = 1;
|
||||
mobj->momy = 0;
|
||||
S_StartSound(mobj, mobj->info->deathsound);
|
||||
mobj->flags &= ~MF_NOCLIPTHING;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
P_SpawnGhostMobj(mobj);
|
||||
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
|
||||
P_InstaThrust(mobj, mobj->angle, mobj->info->speed);
|
||||
|
||||
P_SpawnGhostMobj(mobj);
|
||||
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
|
||||
P_InstaThrust(mobj, mobj->angle, mobj->info->speed);
|
||||
if (grounded)
|
||||
{
|
||||
sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj);
|
||||
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|
||||
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
|
||||
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
|
||||
K_DoPogoSpring(mobj, 0, false);
|
||||
}
|
||||
|
||||
sec2 = P_ThingOnSpecial3DFloor(mobj);
|
||||
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|
||||
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
|
||||
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
|
||||
K_DoPogoSpring(mobj, 0, false);
|
||||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
|
||||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
|
||||
if (leveltime % TICRATE == 0)
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
if (leveltime % TICRATE == 0)
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -8214,13 +8317,41 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
break;
|
||||
case MT_THUNDERSHIELD:
|
||||
{
|
||||
fixed_t destx, desty;
|
||||
if (!mobj->target || !mobj->target->health || (mobj->target->player && mobj->target->player->kartstuff[k_curshield] != 1))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
P_SetScale(mobj, (mobj->destscale = (5*mobj->target->destscale)>>2));
|
||||
|
||||
if (!splitscreen /*&& rendermode != render_soft*/)
|
||||
{
|
||||
angle_t viewingangle;
|
||||
statenum_t curstate = ((mobj->tics == 1) ? (mobj->state->nextstate) : ((statenum_t)(mobj->state-states)));
|
||||
|
||||
if (players[displayplayer].awayviewtics)
|
||||
viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
|
||||
else if (!camera.chase && players[displayplayer].mo)
|
||||
viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
|
||||
else
|
||||
viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, camera.x, camera.y);
|
||||
|
||||
if (curstate > S_THUNDERSHIELD15)
|
||||
viewingangle += ANGLE_180;
|
||||
destx = mobj->target->x + P_ReturnThrustX(mobj->target, viewingangle, mobj->scale>>4);
|
||||
desty = mobj->target->y + P_ReturnThrustY(mobj->target, viewingangle, mobj->scale>>4);
|
||||
}
|
||||
else
|
||||
{
|
||||
destx = mobj->target->x;
|
||||
desty = mobj->target->y;
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj, destx, desty, mobj->target->z);
|
||||
break;
|
||||
}
|
||||
case MT_KARMAHITBOX:
|
||||
if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator
|
||||
|| (G_RaceGametype() || mobj->target->player->kartstuff[k_bumper]))
|
||||
|
@ -8869,6 +9000,41 @@ void P_SceneryThinker(mobj_t *mobj)
|
|||
}
|
||||
|
||||
P_CycleMobjState(mobj);
|
||||
|
||||
if (mobj->type != MT_RANDOMAUDIENCE)
|
||||
return;
|
||||
|
||||
{
|
||||
if (!mobj->colorized) // a fan of someone?
|
||||
return;
|
||||
|
||||
if (mobj->threshold >= 0) // not already happy or sad?
|
||||
{
|
||||
if (!playeringame[mobj->threshold] || players[mobj->threshold].spectator) // focused on a valid player?
|
||||
return;
|
||||
|
||||
if (!(players[mobj->threshold].exiting) && !(players[mobj->threshold].pflags & PF_TIMEOVER)) // not finished yet?
|
||||
return;
|
||||
|
||||
if (K_IsPlayerLosing(&players[mobj->threshold]))
|
||||
mobj->threshold = -2;
|
||||
else
|
||||
{
|
||||
mobj->threshold = -1;
|
||||
S_StartSound(mobj, sfx_chaooo);
|
||||
}
|
||||
}
|
||||
|
||||
if (mobj->threshold == -1)
|
||||
mobj->angle += ANGLE_22h;
|
||||
|
||||
if (((statenum_t)(mobj->state-states) != S_AUDIENCE_CHAO_CHEER2) || (mobj->tics != states[S_AUDIENCE_CHAO_CHEER2].tics)) // not at the start of your cheer jump?
|
||||
return;
|
||||
|
||||
mobj->momz = 0;
|
||||
|
||||
P_SetMobjState(mobj, ((mobj->threshold == -1) ? S_AUDIENCE_CHAO_WIN2 : S_AUDIENCE_CHAO_LOSE));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -9116,9 +9282,43 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
}
|
||||
break;
|
||||
case MT_BIGRING:
|
||||
mobj->destscale = 3*FRACUNIT;
|
||||
P_SetScale(mobj, 3*FRACUNIT);
|
||||
P_SetScale(mobj, (mobj->destscale = 3*FRACUNIT));
|
||||
break;
|
||||
case MT_RANDOMAUDIENCE:
|
||||
{
|
||||
fixed_t randu = P_RandomFixed();
|
||||
P_SetScale(mobj, (mobj->destscale <<= 1));
|
||||
if (randu < (FRACUNIT/9)) // a fan of someone?
|
||||
{
|
||||
UINT8 i, pcount = 0;
|
||||
UINT8 pnum[MAXPLAYERS];
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
pnum[pcount] = i;
|
||||
pcount++;
|
||||
}
|
||||
|
||||
if (pcount)
|
||||
{
|
||||
mobj->threshold = pnum[P_RandomKey(pcount)];
|
||||
mobj->color = players[mobj->threshold].skincolor;
|
||||
mobj->colorized = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (randu > (FRACUNIT/2))
|
||||
{
|
||||
mobj->color = P_RandomKey(MAXSKINCOLORS-1)+1;
|
||||
break;
|
||||
}
|
||||
|
||||
mobj->color = SKINCOLOR_AQUA;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -9129,6 +9329,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
case MT_BIGMACE: case MT_SMALLMACE:
|
||||
case MT_FALLINGROCK:
|
||||
//case MT_RANDOMITEM:
|
||||
case MT_FLOATINGITEM:
|
||||
case MT_BATTLEBUMPER:
|
||||
case MT_BANANA: case MT_BANANA_SHIELD:
|
||||
//case MT_FAKEITEM: case MT_FAKESHIELD:
|
||||
|
@ -9136,6 +9337,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
case MT_JAWZ: case MT_JAWZ_DUD: case MT_JAWZ_SHIELD:
|
||||
case MT_SSMINE: case MT_SSMINE_SHIELD:
|
||||
case MT_BALLHOG: case MT_SINK:
|
||||
case MT_THUNDERSHIELD:
|
||||
P_SpawnShadowMobj(mobj);
|
||||
default:
|
||||
break;
|
||||
|
@ -9228,6 +9430,8 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
|
|||
if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->mobj_scale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
|
||||
mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
|
||||
|
||||
P_SetScale(mobj, mobj->destscale);
|
||||
|
||||
// set subsector and/or block links
|
||||
P_SetThingPosition(mobj);
|
||||
I_Assert(mobj->subsector != NULL);
|
||||
|
@ -10875,6 +11079,8 @@ ML_NOCLIMB : Direction not controllable
|
|||
else if (i == MT_BOSS3WAYPOINT) // SRB2kart 120217 - Used to store checkpoint num
|
||||
{
|
||||
mobj->health = mthing->angle;
|
||||
P_SetTarget(&mobj->tracer, waypointcap);
|
||||
P_SetTarget(&waypointcap, mobj);
|
||||
}
|
||||
else if (i == MT_SPIKE)
|
||||
{
|
||||
|
|
|
@ -429,6 +429,8 @@ typedef struct actioncache_s
|
|||
|
||||
extern actioncache_t actioncachehead;
|
||||
|
||||
extern mobj_t *waypointcap;
|
||||
|
||||
void P_InitCachedActions(void);
|
||||
void P_RunCachedActions(void);
|
||||
void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
|
||||
|
|
|
@ -945,11 +945,10 @@ typedef enum
|
|||
MD2_EXTVAL2 = 1<<6,
|
||||
MD2_HNEXT = 1<<7,
|
||||
MD2_HPREV = 1<<8,
|
||||
MD2_COLORIZED = 1<<9,
|
||||
MD2_WAYPOINTCAP = 1<<10
|
||||
#ifdef ESLOPE
|
||||
MD2_SLOPE = 1<<9,
|
||||
MD2_COLORIZED = 1<<10
|
||||
#else
|
||||
MD2_COLORIZED = 1<<9
|
||||
, MD2_SLOPE = 1<<11
|
||||
#endif
|
||||
} mobj_diff2_t;
|
||||
|
||||
|
@ -1146,6 +1145,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
#endif
|
||||
if (mobj->colorized)
|
||||
diff2 |= MD2_COLORIZED;
|
||||
if (mobj == waypointcap)
|
||||
diff2 |= MD2_WAYPOINTCAP;
|
||||
if (diff2 != 0)
|
||||
diff |= MD_MORE;
|
||||
|
||||
|
@ -2165,6 +2166,9 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
|||
|
||||
P_AddThinker(&mobj->thinker);
|
||||
|
||||
if (diff2 & MD2_WAYPOINTCAP)
|
||||
P_SetTarget(&waypointcap, mobj);
|
||||
|
||||
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
|
||||
#include "v_video.h"
|
||||
|
||||
#include "filesrch.h" // refreshdirmenu
|
||||
|
||||
// wipes
|
||||
#include "f_finale.h"
|
||||
|
||||
|
@ -3132,6 +3134,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
|||
|
||||
if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX)
|
||||
{
|
||||
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||
CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -251,7 +251,7 @@ void P_SpawnSlope_Line(int linenum)
|
|||
UINT8 flags = 0; // Slope flags
|
||||
if (line->flags & ML_NOSONIC)
|
||||
flags |= SL_NOPHYSICS;
|
||||
if (line->flags & ML_NOTAILS)
|
||||
if (!(line->flags & ML_NOTAILS))
|
||||
flags |= SL_NODYNAMIC;
|
||||
if (line->flags & ML_NOKNUX)
|
||||
flags |= SL_ANCHORVERTEX;
|
||||
|
|
|
@ -180,6 +180,7 @@ void Command_CountMobjs_f(void)
|
|||
void P_InitThinkers(void)
|
||||
{
|
||||
thinkercap.prev = thinkercap.next = &thinkercap;
|
||||
waypointcap = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -920,6 +920,16 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
|
||||
{
|
||||
if (vis->scalestep) // currently papersprites only
|
||||
{
|
||||
#ifndef RANGECHECK
|
||||
if ((frac>>FRACBITS) < 0 || (frac>>FRACBITS) >= SHORT(patch->width)) // if this doesn't work i'm removing papersprites
|
||||
break;
|
||||
#endif
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||
spryscale += vis->scalestep;
|
||||
}
|
||||
#ifdef RANGECHECK
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
|
||||
|
@ -929,16 +939,10 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
#else
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
if (vis->scalestep)
|
||||
{
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||
}
|
||||
if (vis->vflip)
|
||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||
else
|
||||
R_DrawMaskedColumn(column);
|
||||
spryscale += vis->scalestep;
|
||||
}
|
||||
|
||||
colfunc = basecolfunc;
|
||||
|
@ -1262,7 +1266,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
offset2 = FixedMul(spritecachedinfo[lump].width, this_scale);
|
||||
tx += FixedMul(offset2, ang_scale);
|
||||
x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1);
|
||||
x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - 1;
|
||||
|
||||
// off the left side
|
||||
if (x2 < 0)
|
||||
|
@ -1271,7 +1275,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (papersprite)
|
||||
{
|
||||
fixed_t yscale2, cosmul, sinmul, tz2;
|
||||
INT32 range;
|
||||
|
||||
if (x2 <= x1)
|
||||
return;
|
||||
|
||||
if (ang >= ANGLE_180)
|
||||
{
|
||||
|
@ -1301,12 +1307,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
|
||||
return;
|
||||
|
||||
if (x2 > x1)
|
||||
range = (x2 - x1);
|
||||
else
|
||||
range = 1;
|
||||
|
||||
scalestep = (yscale2 - yscale)/range;
|
||||
scalestep = (yscale2 - yscale)/(x2 - x1);
|
||||
|
||||
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
|
||||
// sortscale = max(yscale, yscale2);
|
||||
|
|
|
@ -815,6 +815,9 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"hogbom", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR},
|
||||
{"kpogos", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR},
|
||||
{"ddash", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
|
||||
{"zio3", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR},
|
||||
{"mcitm1", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR},
|
||||
{"chaooo", false, 110, 0, -1, NULL, 0, -1, -1, LUMPERROR},
|
||||
{"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
|
||||
{"dbgsal", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR},
|
||||
|
||||
|
|
|
@ -890,6 +890,9 @@ typedef enum
|
|||
sfx_hogbom,
|
||||
sfx_kpogos,
|
||||
sfx_ddash,
|
||||
sfx_zio3,
|
||||
sfx_mcitm1,
|
||||
sfx_chaooo,
|
||||
sfx_itfree,
|
||||
sfx_dbgsal,
|
||||
|
||||
|
|
|
@ -1253,6 +1253,7 @@ void V_DrawFadeConsBack(INT32 plines)
|
|||
//
|
||||
UINT8 *V_GetStringColormap(INT32 colorflags)
|
||||
{
|
||||
#if 0 // perfect
|
||||
switch ((colorflags & V_CHARCOLORMASK) >> V_CHARCOLORSHIFT)
|
||||
{
|
||||
case 1: // 0x81, purple
|
||||
|
@ -1288,6 +1289,12 @@ UINT8 *V_GetStringColormap(INT32 colorflags)
|
|||
default: // reset
|
||||
return NULL;
|
||||
}
|
||||
#else // optimised
|
||||
colorflags = ((colorflags & V_CHARCOLORMASK) >> V_CHARCOLORSHIFT);
|
||||
if (!colorflags || colorflags > 15) // INT32 is signed, but V_CHARCOLORMASK is a very restrictive mask.
|
||||
return NULL;
|
||||
return (purplemap+((colorflags-1)<<8));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Writes a single character (draw WHITE if bit 7 set)
|
||||
|
|
76
src/w_wad.c
76
src/w_wad.c
|
@ -34,6 +34,8 @@
|
|||
#include "z_zone.h"
|
||||
#include "fastcmp.h"
|
||||
|
||||
#include "filesrch.h"
|
||||
|
||||
#include "i_video.h" // rendermode
|
||||
#include "d_netfil.h"
|
||||
#include "dehacked.h"
|
||||
|
@ -294,12 +296,22 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
UINT32 numlumps;
|
||||
size_t i;
|
||||
INT32 compressed = 0;
|
||||
size_t packetsize = 0;
|
||||
serverinfo_pak *dummycheck = NULL;
|
||||
size_t packetsize;
|
||||
UINT8 md5sum[16];
|
||||
boolean important;
|
||||
|
||||
// Shut the compiler up.
|
||||
(void)dummycheck;
|
||||
if (!(refreshdirmenu & REFRESHDIR_ADDFILE))
|
||||
refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier
|
||||
|
||||
if (refreshdirname)
|
||||
Z_Free(refreshdirname);
|
||||
if (dirmenu)
|
||||
{
|
||||
refreshdirname = Z_StrDup(filename);
|
||||
nameonly(refreshdirname);
|
||||
}
|
||||
else
|
||||
refreshdirname = NULL;
|
||||
|
||||
//CONS_Debug(DBG_SETUP, "Loading %s\n", filename);
|
||||
//
|
||||
|
@ -308,6 +320,7 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
if (numwadfiles >= MAX_WADFILES)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
||||
refreshdirmenu |= REFRESHDIR_MAX;
|
||||
return INT16_MAX;
|
||||
}
|
||||
|
||||
|
@ -317,21 +330,21 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
|
||||
// Check if wad files will overflow fileneededbuffer. Only the filename part
|
||||
// is send in the packet; cf.
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
// see PutFileNeeded in d_netfil.c
|
||||
if ((important = !W_VerifyNMUSlumps(filename)))
|
||||
{
|
||||
packetsize += nameonlylength(wadfiles[i]->filename);
|
||||
packetsize += 22; // MD5, etc.
|
||||
}
|
||||
packetsize = packetsizetally + nameonlylength(filename) + 22;
|
||||
|
||||
packetsize += nameonlylength(filename);
|
||||
packetsize += 22;
|
||||
if (packetsize > MAXFILENEEDED*sizeof(UINT8))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
||||
refreshdirmenu |= REFRESHDIR_MAX;
|
||||
if (handle)
|
||||
fclose(handle);
|
||||
return INT16_MAX;
|
||||
}
|
||||
|
||||
if (packetsize > sizeof(dummycheck->fileneeded))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
||||
if (handle)
|
||||
fclose(handle);
|
||||
return INT16_MAX;
|
||||
packetsizetally = packetsize;
|
||||
}
|
||||
|
||||
// detect dehacked file with the "soc" extension
|
||||
|
@ -470,6 +483,7 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
wadfile->handle = handle;
|
||||
wadfile->numlumps = (UINT16)numlumps;
|
||||
wadfile->lumpinfo = lumpinfo;
|
||||
wadfile->important = important;
|
||||
fseek(handle, 0, SEEK_END);
|
||||
wadfile->filesize = (unsigned)ftell(handle);
|
||||
|
||||
|
@ -1240,19 +1254,27 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
|
|||
*/
|
||||
int W_VerifyNMUSlumps(const char *filename)
|
||||
{
|
||||
// MIDI, MOD/S3M/IT/XM/OGG/MP3/WAV, WAVE SFX
|
||||
// ENDOOM text and palette lumps
|
||||
lumpchecklist_t NMUSlist[] =
|
||||
{
|
||||
{"D_", 2},
|
||||
{"O_", 2},
|
||||
{"DS", 2},
|
||||
{"ENDOOM", 6},
|
||||
{"PLAYPAL", 7},
|
||||
{"COLORMAP", 8},
|
||||
{"PAL", 3},
|
||||
{"CLM", 3},
|
||||
{"TRANS", 5},
|
||||
{"D_", 2}, // MIDI music
|
||||
{"O_", 2}, // Digital music
|
||||
{"DS", 2}, // Sound effects
|
||||
|
||||
{"ENDOOM", 6}, // ENDOOM text lump
|
||||
{"PLAYPAL", 7}, // Palette
|
||||
{"COLORMAP", 8}, // Colormap
|
||||
{"PAL", 3}, // Palette changes
|
||||
{"CLM", 3}, // Colormap changes
|
||||
{"TRANS", 5}, // Translucency map
|
||||
|
||||
{"LTFNT", 5}, // Level title font changes
|
||||
{"STCFN", 5}, // Console font changes
|
||||
{"TNYFN", 5}, // Tiny console font changes
|
||||
{"MKFNT", 5}, // Kart font changes
|
||||
|
||||
{"M_", 2}, // Menu changes
|
||||
{"K_", 2}, // Kart graphic changes
|
||||
|
||||
{NULL, 0},
|
||||
};
|
||||
return W_VerifyFile(filename, NMUSlist, false);
|
||||
|
|
|
@ -70,6 +70,7 @@ typedef struct wadfile_s
|
|||
FILE *handle;
|
||||
UINT32 filesize; // for network
|
||||
UINT8 md5sum[16];
|
||||
boolean important;
|
||||
} wadfile_t;
|
||||
|
||||
#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word
|
||||
|
|
Loading…
Reference in a new issue