Merge branch 'next'

This commit is contained in:
Alam Ed Arias 2015-01-01 14:51:38 -05:00
commit 2b2b23efab
47 changed files with 1619 additions and 2034 deletions

View File

@ -1,4 +1,4 @@
Here it is! SRB2 v2.1.12 source code!
Here it is! SRB2 v2.1.14 source code!
(why do we keep the version number up to date
when everything else in this file is hilariously old?
- Inuyasha)

View File

@ -379,11 +379,13 @@ void COM_AddCommand(const char *name, com_func_t func)
{
if (!stricmp(name, cmd->name)) //case insensitive now that we have lower and uppercase!
{
#ifdef HAVE_BLUA
// don't I_Error for Lua commands
// Lua commands can replace game commands, and they have priority.
// BUT, if for some reason we screwed up and made two console commands with the same name,
// it's good to have this here so we find out.
if (cmd->function != COM_Lua_f)
#endif
I_Error("Command %s already exists\n", name);
return;
@ -397,6 +399,7 @@ void COM_AddCommand(const char *name, com_func_t func)
com_commands = cmd;
}
#ifdef HAVE_BLUA
/** Adds a console command for Lua.
* No I_Errors allowed; return a negative code instead.
*
@ -429,6 +432,7 @@ int COM_AddLuaCommand(const char *name)
com_commands = cmd;
return 0;
}
#endif
/** Tests if a command exists.
*
@ -1284,6 +1288,8 @@ void CV_LoadNetVars(UINT8 **p)
serverloading = false;
}
static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth);
void CV_ResetCheatNetVars(void)
{
consvar_t *cvar;
@ -1291,7 +1297,7 @@ void CV_ResetCheatNetVars(void)
// Stealthset everything back to default.
for (cvar = consvar_vars; cvar; cvar = cvar->next)
if (cvar->flags & CV_CHEAT)
Setvalue(cvar, cvar->defaultvalue, true);
CV_SetCVar(cvar, cvar->defaultvalue, true);
}
// Returns true if the variable's current value is its default value
@ -1428,11 +1434,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
INT32 newvalue, max;
// count pointlimit better
if (var == &cv_pointlimit && (gametype == GT_MATCH
#ifdef CHAOSISNOTDEADYET
|| gametype == GT_CHAOS
#endif
))
if (var == &cv_pointlimit && (gametype == GT_MATCH))
increment *= 50;
newvalue = var->value + increment;

View File

@ -823,7 +823,7 @@ static inline void resynch_read_ctf(resynchend_pak *p)
{
if (!playeringame[p->flagplayer[1]])
I_Error("Invalid blue flag player %d who isn't in the game!", (INT32)p->flagplayer[1]);
players[p->flagplayer[1]].gotflag = GF_REDFLAG;
players[p->flagplayer[1]].gotflag = GF_BLUEFLAG;
if (blueflag)
{
P_RemoveMobj(blueflag);

View File

@ -90,6 +90,9 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#include "hardware/hw3sound.h"
#endif
// platform independant focus loss
UINT8 window_notinfocus = false;
//
// DEMO LOOP
//
@ -437,6 +440,17 @@ static void D_Display(void)
CON_Drawer();
M_Drawer(); // menu is drawn even on top of everything
// focus lost notification goes on top of everything, even the former everything
if (window_notinfocus)
{
M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2);
if (gamestate == GS_LEVEL && (P_AutoPause() || paused))
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Game Paused");
else
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Focus Lost");
}
NetUpdate(); // send out any new accumulation
// It's safe to end the game now.
@ -635,6 +649,7 @@ void D_AdvanceDemo(void)
//
void D_StartTitle(void)
{
INT32 i;
if (netgame)
{
if (gametype == GT_COOP)
@ -661,6 +676,16 @@ void D_StartTitle(void)
SV_StopServer();
SV_ResetServer();
for (i = 0; i < MAXPLAYERS; i++)
CL_ClearPlayer(i);
splitscreen = false;
SplitScreen_OnChange();
botingame = false;
botskin = 0;
cv_debug = 0;
emeralds = 0;
// In case someone exits out at the same time they start a time attack run,
// reset modeattacking
modeattacking = ATTACKING_NONE;
@ -803,7 +828,7 @@ static void IdentifyVersion(void)
D_AddFile(va(pandf,srb2waddir,"rings.dta"));
// Add our crappy patches to fix our bugs
D_AddFile(va(pandf,srb2waddir,"patch.dta"));
// D_AddFile(va(pandf,srb2waddir,"patch.dta"));
#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
{
@ -1087,19 +1112,19 @@ void D_SRB2Main(void)
#endif
D_CleanFile();
#if 1 // md5s last updated 11/10/14
#if 1 // md5s last updated 12/14/14
// Check MD5s of autoloaded files
W_VerifyFileMD5(0, "ac309fb3c7d4b5b685e2cd26beccf0e8"); // srb2.srb/srb2.wad
W_VerifyFileMD5(1, "f39b6c849295e3c81875726e8cc0e2c7"); // zones.dta
W_VerifyFileMD5(0, "c1b9577687f8a795104aef4600720ea7"); // srb2.srb/srb2.wad
W_VerifyFileMD5(1, "303838c6c534d9540288360fa49cca60"); // zones.dta
W_VerifyFileMD5(2, "cfca0f1c73023cbbd8f844f45480f799"); // player.dta
W_VerifyFileMD5(3, "85901ad4bf94637e5753d2ac2c03ea26"); // rings.dta
W_VerifyFileMD5(4, "a45cc59d13dce924f2112b3e4201d0ae"); // patch.dta
//W_VerifyFileMD5(4, "0c66790502e648bfce90fdc5bb15722e"); // patch.dta
// don't check music.dta 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.
#endif
mainwads = 5; // there are 5 wads not to unload
mainwads = 4; // there are 5 wads not to unload
cht_Init();

View File

@ -277,21 +277,6 @@ consvar_t cv_matchboxes = {"matchboxes", "Normal", CV_NETVAR|CV_CHEAT, matchboxe
consvar_t cv_specialrings = {"specialrings", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_powerstones = {"powerstones", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#ifdef CHAOSISNOTDEADYET
consvar_t cv_chaos_bluecrawla = {"chaos_bluecrawla", "8", CV_NETVAR, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chaos_redcrawla = {"chaos_redcrawla", "8", CV_NETVAR, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chaos_crawlacommander = {"chaos_crawlacommander", "2", CV_NETVAR, chances_cons_t,
NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chaos_jettysynbomber = {"chaos_jettysynbomber", "5", CV_NETVAR, chances_cons_t,
NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chaos_jettysyngunner = {"chaos_jettysyngunner", "2", CV_NETVAR, chances_cons_t,
NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chaos_eggmobile1 = {"chaos_eggmobile1", "2", CV_NETVAR, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chaos_eggmobile2 = {"chaos_eggmobile2", "2", CV_NETVAR, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chaos_skim = {"chaos_skim", "5", CV_NETVAR, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chaos_spawnrate = {"chaos_spawnrate", "30",CV_NETVAR, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
consvar_t cv_recycler = {"tv_recycler", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_teleporters = {"tv_teleporter", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_superring = {"tv_superring", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -498,18 +483,6 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_competitionboxes);
CV_RegisterVar(&cv_matchboxes);
#ifdef CHAOSISNOTDEADYET
CV_RegisterVar(&cv_chaos_bluecrawla);
CV_RegisterVar(&cv_chaos_redcrawla);
CV_RegisterVar(&cv_chaos_crawlacommander);
CV_RegisterVar(&cv_chaos_jettysynbomber);
CV_RegisterVar(&cv_chaos_jettysyngunner);
CV_RegisterVar(&cv_chaos_eggmobile1);
CV_RegisterVar(&cv_chaos_eggmobile2);
CV_RegisterVar(&cv_chaos_skim);
CV_RegisterVar(&cv_chaos_spawnrate);
#endif
CV_RegisterVar(&cv_recycler);
CV_RegisterVar(&cv_teleporters);
CV_RegisterVar(&cv_superring);
@ -699,6 +672,8 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_invertmouse2);
CV_RegisterVar(&cv_mousesens);
CV_RegisterVar(&cv_mousesens2);
CV_RegisterVar(&cv_mouseysens);
CV_RegisterVar(&cv_mouseysens2);
CV_RegisterVar(&cv_mousemove);
CV_RegisterVar(&cv_mousemove2);
@ -734,9 +709,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_scr_width);
CV_RegisterVar(&cv_scr_height);
// p_fab.c
CV_RegisterVar(&cv_translucency);
CV_RegisterVar(&cv_soundtest);
// ingame object placing
@ -3374,18 +3346,6 @@ void D_GameTypeChanged(INT32 lastgametype)
switch (gametype)
{
#ifdef CHAOSISNOTDEADYET
case GT_CHAOS:
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
{
// default settings for chaos: timelimit 2 mins, no pointlimit
CV_SetValue(&cv_pointlimit, 0);
CV_SetValue(&cv_timelimit, 2);
}
if (!cv_itemrespawntime.changed)
CV_SetValue(&cv_itemrespawntime, 90); // respawn sparingly in chaos
break;
#endif
case GT_MATCH:
case GT_TEAMMATCH:
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
@ -3905,14 +3865,18 @@ static void Command_Cheats_f(void)
{
if (COM_CheckParm("off"))
{
CV_ResetCheatNetVars();
if (!(server || (adminplayer == consoleplayer)))
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
else
CV_ResetCheatNetVars();
return;
}
if (CV_CheatsEnabled())
{
CONS_Printf(M_GetText("At least one CHEAT-marked variable has been changed -- Cheats are enabled.\n"));
CONS_Printf(M_GetText("Type CHEATS OFF to reset all cheat variables to default.\n"));
if (server || (adminplayer == consoleplayer))
CONS_Printf(M_GetText("Type CHEATS OFF to reset all cheat variables to default.\n"));
}
else
CONS_Printf(M_GetText("No CHEAT-marked variables are changed -- Cheats are disabled.\n"));

View File

@ -44,6 +44,7 @@ extern consvar_t cv_invertmouse2;
extern consvar_t cv_alwaysfreelook2;
extern consvar_t cv_mousemove2;
extern consvar_t cv_mousesens2;
extern consvar_t cv_mouseysens2;
// normally in p_mobj but the .h is not read
extern consvar_t cv_itemrespawntime;
@ -80,7 +81,6 @@ extern consvar_t cv_useranalog, cv_useranalog2;
extern consvar_t cv_analog, cv_analog2;
extern consvar_t cv_netstat;
extern consvar_t cv_translucency;
extern consvar_t cv_splats;
extern consvar_t cv_countdowntime;
@ -113,12 +113,6 @@ extern consvar_t cv_ringslinger, cv_soundtest;
extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes;
#ifdef CHAOSISNOTDEADYET
extern consvar_t cv_chaos_spawnrate, cv_chaos_bluecrawla, cv_chaos_redcrawla;
extern consvar_t cv_chaos_crawlacommander, cv_chaos_jettysynbomber, cv_chaos_jettysyngunner;
extern consvar_t cv_chaos_eggmobile1, cv_chaos_eggmobile2, cv_chaos_skim;
#endif
#ifdef NEWPING
extern consvar_t cv_maxping;
#endif

View File

@ -5052,7 +5052,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_ARROWDOWN",
// Trapgoyle Demon fire
"S_DEMONFIRE",
"S_DEMONFIRE1",
"S_DEMONFIRE2",
"S_DEMONFIRE3",
"S_DEMONFIRE4",
"S_DEMONFIRE5",
"S_DEMONFIRE6",
"S_GFZFLOWERA",
"S_GFZFLOWERA2",
@ -7062,7 +7067,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_NIGHTOPIANHELPER", // the actual helper object that orbits you
// Utility Objects
"MT_CHAOSSPAWNER",
"MT_TELEPORTMAN",
"MT_ALTVIEWMAN",
"MT_CRUMBLEOBJ", // Sound generator for crumbling platform
@ -7453,6 +7457,17 @@ struct {
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_TRANSMASK",FF_TRANSMASK},
{"FF_TRANSSHIFT",FF_TRANSSHIFT},
// new preshifted translucency (used in source)
{"FF_TRANS10",FF_TRANS10},
{"FF_TRANS20",FF_TRANS20},
{"FF_TRANS30",FF_TRANS30},
{"FF_TRANS40",FF_TRANS40},
{"FF_TRANS50",FF_TRANS50},
{"FF_TRANS60",FF_TRANS60},
{"FF_TRANS70",FF_TRANS70},
{"FF_TRANS80",FF_TRANS80},
{"FF_TRANS90",FF_TRANS90},
// compatibility
// Transparency for SOCs is pre-shifted
{"TR_TRANS10",tr_trans10<<FF_TRANSSHIFT},
{"TR_TRANS20",tr_trans20<<FF_TRANSSHIFT},
@ -8047,7 +8062,7 @@ static fixed_t find_const(const char **rword)
return r;
}
if (!*(word+1) && // Turn a single A-z symbol into numbers, like sprite frames.
(*word >= 'A' && *word <= 'Z') || (*word >= 'a' && *word <= 'z')) {
((*word >= 'A' && *word <= 'Z') || (*word >= 'a' && *word <= 'z'))) {
r = R_Char2Frame(*word);
free(word);
return r;

View File

@ -144,8 +144,8 @@ extern FILE *logstream;
#define VERSIONSTRING "Trunk"
#else
#define VERSION 201 // Game version
#define SUBVERSION 12 // more precise version number
#define VERSIONSTRING "v2.1.12"
#define SUBVERSION 14 // more precise version number
#define VERSIONSTRING "v2.1.14"
// Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates!
#endif
@ -203,7 +203,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 17
#define MODVERSION 19
@ -449,10 +449,6 @@ extern const char *compdate, *comptime, *comprevision;
/// Dumps the contents of a network save game upon consistency failure for debugging.
//#define DUMPCONSISTENCY
/// Pre-1.08 Chaos gametype code
/// \note Code severely out of date, does not take new enemies/bosses into account.
//#define CHAOSISNOTDEADYET
/// Polyobject fake flat code
#define POLYOBJECTS_PLANES

View File

@ -103,6 +103,7 @@ extern boolean digital_disabled;
extern boolean menuactive; // Menu overlaid?
extern UINT8 paused; // Game paused?
extern UINT8 window_notinfocus; // are we in focus? (backend independant -- handles auto pausing and display of "focus lost" message)
extern boolean nodrawers;
extern boolean noblit;

View File

@ -967,7 +967,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
// why build a ticcmd if we're paused?
// Or, for that matter, if we're being reborn.
if (paused || P_MenuActivePause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN))
if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN))
{
cmd->angleturn = (INT16)(localangle >> 16);
cmd->aiming = G_ClipAimingPitch(&localaiming);
@ -1257,7 +1257,7 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
//why build a ticcmd if we're paused?
// Or, for that matter, if we're being reborn.
if (paused || P_MenuActivePause() || player->playerstate == PST_REBORN)
if (paused || P_AutoPause() || player->playerstate == PST_REBORN)
{
cmd->angleturn = (INT16)(localangle2 >> 16);
cmd->aiming = G_ClipAimingPitch(&localaiming2);
@ -2299,11 +2299,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
// -- DM/Tag/CTF-spectator/etc --
// Order: DM->CTF->Coop
else if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF
|| ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && !(players[playernum].pflags & PF_TAGIT))
#ifdef CHAOSISNOTDEADYET
|| gametype == GT_CHAOS
#endif
)
|| ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && !(players[playernum].pflags & PF_TAGIT)))
{
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
&& !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start
@ -2709,9 +2705,6 @@ INT16 G_TOLFlag(INT32 pgametype)
if (pgametype == GT_RACE) return TOL_RACE;
if (pgametype == GT_MATCH) return TOL_MATCH;
if (pgametype == GT_TEAMMATCH) return TOL_MATCH;
#ifdef CHAOSISNOTDEADYET
if (pgametype == GT_CHAOS) return TOL_CHAOS;
#endif
if (pgametype == GT_TAG) return TOL_TAG;
if (pgametype == GT_HIDEANDSEEK) return TOL_TAG;
if (pgametype == GT_CTF) return TOL_CTF;

View File

@ -28,6 +28,8 @@ static CV_PossibleValue_t onecontrolperkey_cons_t[] = {{1, "One"}, {2, "Several"
// mouse values are used once
consvar_t cv_mousesens = {"mousesens", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mousesens2 = {"mousesens2", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mouseysens = {"mouseysens", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mouseysens2 = {"mouseysens2", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
INT32 mousex, mousey;
@ -99,7 +101,7 @@ void G_MapEventsToControls(event_t *ev)
case ev_mouse: // buttons are virtual keys
mousex = (INT32)(ev->data2*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f));
mousey = (INT32)(ev->data3*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f));
mlooky = mousey;
mlooky = (INT32)(ev->data3*((cv_mouseysens.value*cv_mousesens.value)/110.0f + 0.1f));
break;
case ev_joystick: // buttons are virtual keys
@ -121,7 +123,7 @@ void G_MapEventsToControls(event_t *ev)
case ev_mouse2: // buttons are virtual keys
mouse2x = (INT32)(ev->data2*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
mouse2y = (INT32)(ev->data3*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
mlook2y = mouse2y;
mlook2y = (INT32)(ev->data3*((cv_mouseysens2.value*cv_mousesens2.value)/110.0f + 0.1f));
break;
default:

View File

@ -125,7 +125,7 @@ typedef enum
} gamecontrols_e;
// mouse values are used once
extern consvar_t cv_mousesens;
extern consvar_t cv_mousesens, cv_mouseysens;
extern INT32 mousex, mousey;
extern INT32 mlooky; //mousey with mlookSensitivity

View File

@ -278,6 +278,7 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[SMALLREDBALL_L], // SPR_TRLS
&lspr[NOLIGHT], // SPR_CBLL
&lspr[NOLIGHT], // SPR_AROW
&lspr[NOLIGHT], // SPR_CFIR
// Greenflower Scenery
&lspr[NOLIGHT], // SPR_FWR1

View File

@ -3796,7 +3796,9 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
}*/
// shadow is always half as translucent as the sprite itself
if (spr->mobj->flags2 & MF2_SHADOW)
if (!cv_translucency.value)
; // translucency disabled
else if (spr->mobj->flags2 & MF2_SHADOW)
sSurf.FlatColor.s.alpha = 0x20;
else if (spr->mobj->frame & FF_TRANSMASK)
{

View File

@ -39,7 +39,7 @@
#ifdef DEBUG_TO_FILE
static unsigned long nb_frames = 0;
static clock_t my_clock;
FILE *logstream;
FILE *gllogstream;
#endif
static HDC hDC = NULL; // the window's device context
@ -81,8 +81,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
// Initialize once for each new process.
// Return FALSE to fail DLL load.
#ifdef DEBUG_TO_FILE
logstream = fopen("ogllog.txt", "wt");
if (logstream == NULL)
gllogstream = fopen("ogllog.txt", "wt");
if (gllogstream == NULL)
return FALSE;
#endif
DisableThreadLibraryCalls(hinstDLL);
@ -99,10 +99,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
#ifdef DEBUG_TO_FILE
if (logstream)
if (gllogstream)
{
fclose(logstream);
logstream = NULL;
fclose(gllogstream);
gllogstream = NULL;
}
#endif
break;

View File

@ -168,7 +168,6 @@ static boolean gl13 = false; // whether we can use opengl 1.3 functions
// : else do nothing
// Returns :
// -----------------+
#if !(defined (HAVE_SDL) && defined (STATIC3DS))
FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
{
#ifdef DEBUG_TO_FILE
@ -178,13 +177,12 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
va_start (arglist, lpFmt);
vsnprintf (str, 4096, lpFmt, arglist);
va_end (arglist);
if (logstream)
fwrite(str, strlen(str), 1, logstream);
if (gllogstream)
fwrite(str, strlen(str), 1, gllogstream);
#else
(void)lpFmt;
#endif
}
#endif
#ifdef STATIC_OPENGL
/* 1.0 functions */
@ -673,7 +671,7 @@ static void GLProject(GLdouble objX, GLdouble objY, GLdouble objZ,
// -----------------+
void SetModelView(GLint w, GLint h)
{
DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h);
// DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h);
screen_width = w;
screen_height = h;
@ -714,7 +712,7 @@ void SetStates(void)
GLfloat LightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
#endif
DBG_Printf("SetStates()\n");
// DBG_Printf("SetStates()\n");
// Hurdler: not necessary, is it?
pglShadeModel(GL_SMOOTH); // iterate vertice colors

View File

@ -57,9 +57,19 @@
#undef DEBUG_TO_FILE // maybe defined in previous *.h
#define DEBUG_TO_FILE // output debugging msgs to ogllog.txt
#if defined ( HAVE_SDL ) && !defined ( LOGMESSAGES )
// todo: find some way of getting SDL to log to ogllog.txt, without
// interfering with r_opengl.dll
#ifdef HAVE_SDL
#undef DEBUG_TO_FILE
#endif
//#if defined(HAVE_SDL) && !defined(_DEBUG)
//#undef DEBUG_TO_FILE
//#endif
#ifdef DEBUG_TO_FILE
extern FILE *gllogstream;
#endif
#ifndef DRIVER_STRING
// #define USE_PALETTED_TEXTURE
@ -117,9 +127,6 @@ extern PFNglGetString pglGetString;
extern const GLubyte *gl_extensions;
extern RGBA_t myPaletteData[];
#ifndef HAVE_SDL
extern FILE *logstream;
#endif
extern GLint screen_width;
extern GLint screen_height;
extern GLbyte screen_depth;

File diff suppressed because it is too large Load Diff

View File

@ -355,6 +355,7 @@ typedef enum sprite
SPR_TRLS,
SPR_CBLL, // Cannonball
SPR_AROW, // Arrow
SPR_CFIR, // Colored fire of various sorts
// Greenflower Scenery
SPR_FWR1,
@ -1907,7 +1908,12 @@ typedef enum state
S_ARROWDOWN,
// Trapgoyle Demon fire
S_DEMONFIRE,
S_DEMONFIRE1,
S_DEMONFIRE2,
S_DEMONFIRE3,
S_DEMONFIRE4,
S_DEMONFIRE5,
S_DEMONFIRE6,
S_GFZFLOWERA,
S_GFZFLOWERA2,
@ -3934,7 +3940,6 @@ typedef enum mobj_type
MT_NIGHTOPIANHELPER, // the actual helper object that orbits you
// Utility Objects
MT_CHAOSSPAWNER,
MT_TELEPORTMAN,
MT_ALTVIEWMAN,
MT_CRUMBLEOBJ, // Sound generator for crumbling platform

View File

@ -387,9 +387,6 @@ CV_PossibleValue_t gametype_cons_t[] =
{GT_HIDEANDSEEK, "Hide and Seek"},
{GT_CTF, "CTF"},
#ifdef CHAOSISNOTDEADYET
{GT_CHAOS, "Chaos"},
#endif
{0, NULL}
};
consvar_t cv_newgametype = {"newgametype", "Co-op", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL};
@ -1129,7 +1126,9 @@ static menuitem_t OP_MouseOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove, 40},
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 50},
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
NULL, "Mouse Speed", &cv_mousesens, 60},
NULL, "Mouse X Speed", &cv_mousesens, 60},
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
NULL, "Mouse Y Speed", &cv_mouseysens, 70},
};
static menuitem_t OP_Mouse2OptionsMenu[] =
@ -1139,9 +1138,11 @@ static menuitem_t OP_Mouse2OptionsMenu[] =
&cv_mouse2port, 20},
{IT_STRING | IT_CVAR, NULL, "Always MouseLook", &cv_alwaysfreelook2, 30},
{IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove2, 40},
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse2, 50},
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse2, 50},
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
NULL, "Mouse Speed", &cv_mousesens2, 60},
NULL, "Mouse X Speed", &cv_mousesens2, 60},
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
NULL, "Mouse Y Speed", &cv_mouseysens2, 70},
};
static menuitem_t OP_VideoOptionsMenu[] =
@ -1901,9 +1902,6 @@ static void Newgametype_OnChange(void)
(cv_newgametype.value == GT_COMPETITION && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_COMPETITION)) ||
(cv_newgametype.value == GT_RACE && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_RACE)) ||
((cv_newgametype.value == GT_MATCH || cv_newgametype.value == GT_TEAMMATCH) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_MATCH)) ||
#ifdef CHAOSISNOTDEADYET
(cv_newgametype.value == GT_CHAOS && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_CHAOS)) ||
#endif
((cv_newgametype.value == GT_TAG || cv_newgametype.value == GT_HIDEANDSEEK) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_TAG)) ||
(cv_newgametype.value == GT_CTF && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_CTF)))
{
@ -3468,11 +3466,6 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
if (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE))
return true;
#ifdef CHAOSISNOTDEADYET
if (gt == GT_CHAOS && (mapheaderinfo[mapnum]->typeoflevel & TOL_CHAOS))
return true;
#endif
return false;
case LLM_LEVELSELECT:

View File

@ -2715,14 +2715,6 @@ void A_BossDeath(mobj_t *mo)
P_LinedefExecute(LE_BOSSDEAD, mo, NULL);
mo->health = 0;
#ifdef CHAOSISNOTDEADYET
if (mo->flags2 & MF2_CHAOSBOSS)
{
P_RemoveMobj(mo);
return;
}
#endif
// Boss is dead (but not necessarily fleeing...)
// Lua may use this to ignore bosses after they start fleeing
mo->flags2 |= MF2_BOSSDEAD;
@ -5635,10 +5627,11 @@ void A_MixUp(mobj_t *actor)
//
void A_RecyclePowers(mobj_t *actor)
{
#ifdef WEIGHTEDRECYCLER
INT32 i, j, k, numplayers = 0;
#ifdef WEIGHTEDRECYCLER
UINT8 beneficiary = 255;
#endif
UINT8 playerslist[MAXPLAYERS];
UINT8 postscramble[MAXPLAYERS];
@ -5651,6 +5644,11 @@ void A_RecyclePowers(mobj_t *actor)
return;
#endif
#if !defined(WEIGHTEDRECYCLER) && !defined(HAVE_BLUA)
// actor is used in all scenarios but this one, funny enough
(void)actor;
#endif
if (!multiplayer)
return;
@ -5665,9 +5663,11 @@ void A_RecyclePowers(mobj_t *actor)
numplayers++;
postscramble[j] = playerslist[j] = (UINT8)i;
#ifdef WEIGHTEDRECYCLER
// The guy who started the recycle gets the best result
if (actor && actor->target && actor->target->player && &players[i] == actor->target->player)
beneficiary = (UINT8)i;
#endif
// Save powers
for (k = 0; k < NUMPOWERS; k++)
@ -5684,6 +5684,13 @@ void A_RecyclePowers(mobj_t *actor)
return; //nobody to touch!
//shuffle the post scramble list, whee!
// hardcoded 0-1 to 1-0 for two players
if (numplayers == 2)
{
postscramble[0] = playerslist[1];
postscramble[1] = playerslist[0];
}
else
for (j = 0; j < numplayers; j++)
{
UINT8 tempint;
@ -5694,6 +5701,7 @@ void A_RecyclePowers(mobj_t *actor)
postscramble[i] = tempint;
}
#ifdef WEIGHTEDRECYCLER
//the joys of qsort...
if (beneficiary != 255) {
qsort(playerslist, numplayers, sizeof(UINT8), P_RecycleCompare);
@ -5710,6 +5718,7 @@ void A_RecyclePowers(mobj_t *actor)
}
}
}
#endif
// now assign!
for (i = 0; i < numplayers; i++)
@ -5737,137 +5746,6 @@ void A_RecyclePowers(mobj_t *actor)
P_RestoreMusic(&players[recv_pl]);
P_FlashPal(&players[recv_pl], PAL_RECYCLE, 10);
}
#else
INT32 i, numplayers = 0;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_RecyclePowers", actor))
return;
#endif
if (!multiplayer)
return;
numplayers = 0;
// Count the number of players in the game
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE
&& !players[i].exiting && !players[i].powers[pw_super] && !((netgame || multiplayer) && players[i].spectator))
numplayers++;
if (numplayers <= 1)
return; //nobody to touch!
else if (numplayers == 2) //simple swap is all that's needed
{
UINT16 temp[NUMPOWERS];
INT32 weapons;
INT32 weaponheld;
INT32 one = -1, two = 0; // default value 0 to make the compiler shut up
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE
&& !players[i].exiting && !players[i].powers[pw_super] && !((netgame || multiplayer) && players[i].spectator))
{
if (one == -1)
one = i;
else
two = i;
}
for (i = 0; i < NUMPOWERS; i++)
{
if (i == pw_flashing || i == pw_underwater || i == pw_spacetime
|| i == pw_tailsfly || i == pw_extralife || i == pw_super || i == pw_nocontrol)
continue;
temp[i] = players[one].powers[i];
players[one].powers[i] = players[two].powers[i];
players[two].powers[i] = temp[i];
}
//1.1: weapons need to be swapped too
weapons = players[one].ringweapons;
players[one].ringweapons = players[two].ringweapons;
players[two].ringweapons = weapons;
weaponheld = players[one].currentweapon;
players[one].currentweapon = players[two].currentweapon;
players[two].currentweapon = weaponheld;
P_SpawnShieldOrb(players[one].mo->player);
P_SpawnShieldOrb(players[two].mo->player);
P_FlashPal(&players[one], PAL_RECYCLE, 10);
P_FlashPal(&players[two], PAL_RECYCLE, 10);
//piece o' cake, eh?
}
else
{
//well, the cake is a LIE!
UINT16 temp[MAXPLAYERS][NUMPOWERS];
INT32 weapons[MAXPLAYERS];
INT32 weaponheld[MAXPLAYERS];
INT32 counter = 0, j = 0, prandom = 0, recyclefrom = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && players[i].playerstate == PST_LIVE
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super]
&& !((netgame || multiplayer) && players[i].spectator))
{
for (j = 0; j < NUMPOWERS; j++)
temp[counter][j] = players[i].powers[j];
//1.1: ring weapons too
weapons[counter] = players[i].ringweapons;
weaponheld[counter] = players[i].currentweapon;
counter++;
}
}
counter = 0;
// Mix them up!
for (;;)
{
if (counter > 255) // fail-safe to avoid endless loop
break;
prandom = P_Random();
prandom %= numplayers; // I love modular arithmetic, don't you?
if (prandom) // Make sure it's not a useless mix
break;
counter++;
}
counter = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && players[i].playerstate == PST_LIVE
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super]
&& !((netgame || multiplayer) && players[i].spectator))
{
recyclefrom = (counter + prandom) % numplayers;
for (j = 0; j < NUMPOWERS; j++)
{
if (j == pw_flashing || j == pw_underwater || j == pw_spacetime
|| j == pw_tailsfly || j == pw_extralife || j == pw_super || j == pw_nocontrol)
continue;
players[i].powers[j] = temp[recyclefrom][j];
}
//1.1: weapon rings too
players[i].ringweapons = weapons[recyclefrom];
players[i].currentweapon = weaponheld[recyclefrom];
P_SpawnShieldOrb(players[i].mo->player);
P_FlashPal(&players[i], PAL_RECYCLE, 10);
counter++;
}
}
}
for (i = 0; i < MAXPLAYERS; i++) //just for sneakers/invinc.
if (playeringame[i] && players[i].playerstate == PST_LIVE
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super]
&& !((netgame || multiplayer) && players[i].spectator))
if (P_IsLocalPlayer(players[i].mo->player))
P_RestoreMusic(players[i].mo->player);
#endif
S_StartSound(NULL, sfx_gravch); //heh, the sound effect I used is already in
}
@ -6160,13 +6038,7 @@ void A_Boss2Pogo(mobj_t *actor)
goop->momy = FixedMul(FINESINE(fa),ns);
goop->momz = FixedMul(4*FRACUNIT, actor->scale);
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS)
goop->fuse = 5*TICRATE;
else
#endif
goop->fuse = 10*TICRATE;
goop->fuse = 10*TICRATE;
}
actor->reactiontime = 0; // we already shot goop, so don't do it again!
if (actor->info->attacksound)

View File

@ -11,124 +11,5 @@
/// \brief some new action routines, separated from the original doom
/// sources, so that you can include it or remove it easy.
#include "doomdef.h"
#include "g_game.h"
#include "p_local.h"
#include "m_random.h"
static void Translucency_OnChange(void);
/** \brief cv_translucency
console variables to turn on and off translucency
*/
consvar_t cv_translucency = {"translucency", "On", CV_CALL|CV_SAVE, CV_OnOff,
Translucency_OnChange, 0, NULL, NULL, 0, 0, NULL};
/** \brief Reset Translucency
*/
static boolean resettrans = false;
/** \brief The R_SetTrans function
Set the translucency map for each frame state of mobj
\param state1 1st state
\param state2 last state
\param transmap translucency
\return void
*/
static void R_SetTrans(statenum_t state1, statenum_t state2, transnum_t transmap)
{
state_t *state = &states[state1];
do
{
state->frame &= ~FF_TRANSMASK;
if (!resettrans)
state->frame |= (transmap<<FF_TRANSSHIFT);
state++;
} while (state1++ < state2);
}
/** \brief The P_SetTranslucencies function
hack the translucency in the states for a set of standard doom sprites
\return void
*/
static void P_SetTranslucencies(void)
{
R_SetTrans(S_SMOKE1, S_SMOKE5, tr_trans50);
R_SetTrans(S_SPLASH1, 0, tr_trans50);
R_SetTrans(S_SPLASH2, 0, tr_trans70);
R_SetTrans(S_SPLASH3, 0, tr_trans90);
R_SetTrans(S_DRIPA1, S_DRIPC2, tr_trans30);
R_SetTrans(S_BLUECRYSTAL1, S_BLUECRYSTAL1, tr_trans30);
R_SetTrans(S_THOK, 0, tr_trans50); // Thok! mobj
R_SetTrans(S_FLAME1, S_FLAME4, tr_trans50); // Flame
R_SetTrans(S_PARTICLE, S_PARTICLE, tr_trans70);
// Flame jet
R_SetTrans(S_FLAMEJETFLAME1, S_FLAMEJETFLAME1, tr_trans50);
R_SetTrans(S_FLAMEJETFLAME2, S_FLAMEJETFLAME2, tr_trans60);
R_SetTrans(S_FLAMEJETFLAME3, S_FLAMEJETFLAME3, tr_trans70);
R_SetTrans(S_BLACKEGG_GOOP1, S_BLACKEGG_GOOP3, tr_trans50);
R_SetTrans(S_BLACKEGG_GOOP4, 0, tr_trans60);
R_SetTrans(S_BLACKEGG_GOOP5, 0, tr_trans70);
R_SetTrans(S_BLACKEGG_GOOP6, 0, tr_trans80);
R_SetTrans(S_BLACKEGG_GOOP7, 0, tr_trans90);
R_SetTrans(S_CYBRAKDEMONFLAMESHOT_FLY1, S_CYBRAKDEMONFLAMESHOT_DIE, tr_trans50); // Flame
R_SetTrans(S_CYBRAKDEMONFLAMEREST, 0, tr_trans50); // Flame
R_SetTrans(S_CYBRAKDEMONTARGETRETICULE1, S_CYBRAKDEMONTARGETRETICULE14, tr_trans50); // Target
R_SetTrans(S_CYBRAKDEMONTARGETDOT, S_CYBRAKDEMONTARGETDOT, tr_trans50); // Target
R_SetTrans(S_FOG1, S_FOG14, tr_trans50);
// if higher translucency needed, toy around with the other tr_trans variables
// shield translucencies
R_SetTrans(S_ARMA1, S_ARMA16, tr_trans40);
R_SetTrans(S_WIND1, S_WIND8, tr_trans70);
R_SetTrans(S_MAGN1, S_MAGN12, tr_trans40);
R_SetTrans(S_FORC1, S_FORC20, tr_trans50);
R_SetTrans(S_ELEM1, S_ELEM12, tr_trans50);
R_SetTrans(S_PITY1, S_PITY10, tr_trans20); // Not sure if Pity Shield should be translucent or not; I mean, the Genesis sprite it's based off of wasn't...
// translucent spark
R_SetTrans(S_SPRK1, S_SPRK1, tr_trans40);
R_SetTrans(S_SPRK2, S_SPRK4, tr_trans50);
R_SetTrans(S_SPRK5, S_SPRK7, tr_trans60);
R_SetTrans(S_SPRK8, S_SPRK10, tr_trans70);
R_SetTrans(S_SPRK11, S_SPRK13, tr_trans80);
R_SetTrans(S_SPRK14, S_SPRK16, tr_trans90);
R_SetTrans(S_SMALLBUBBLE, S_SMALLBUBBLE1, tr_trans50);
R_SetTrans(S_MEDIUMBUBBLE, S_MEDIUMBUBBLE1, tr_trans50);
R_SetTrans(S_LARGEBUBBLE, S_EXTRALARGEBUBBLE, tr_trans50);
R_SetTrans(S_SPLISH1, S_SPLISH9, tr_trans50);
R_SetTrans(S_TOKEN, S_MOVINGTOKEN, tr_trans50);
R_SetTrans(S_RAIN1, 0, tr_trans50);
}
/** \brief The Translucency_OnChange function
executed when cv_translucency changed
*/
static void Translucency_OnChange(void)
{
if (!cv_translucency.value)
resettrans = true;
P_SetTranslucencies();
resettrans = false;
}
/// \todo
/// This file is now unused, please remove at some point

View File

@ -1590,33 +1590,6 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
case MT_SPIKE:
str = M_GetText("%s was %s by spikes.\n");
break;
#ifdef CHAOSISNOTDEADYET
/* These were obviously made for Chaos, and they're extremely out of date.
We either need to keep them out of the EXE or update them to contain
proper text for all enemies we currently have in the game.
*/
case MT_BLUECRAWLA:
str = M_GetText("%s was %s by a blue crawla!\n");
break;
case MT_REDCRAWLA:
str = M_GetText("%s was %s by a red crawla!\n");
break;
case MT_JETTGUNNER:
str = M_GetText("%s was %s by a jetty-syn gunner!\n");
break;
case MT_JETTBOMBER:
str = M_GetText("%s was %s by a jetty-syn bomber!\n");
break;
case MT_CRAWLACOMMANDER:
str = M_GetText("%s was %s by a crawla commander!\n");
break;
case MT_EGGMOBILE:
str = M_GetText("%s was %s by the Egg Mobile!\n");
break;
case MT_EGGMOBILE2:
str = M_GetText("%s was %s by the Egg Slimer!\n");
break;
#endif
default:
str = M_GetText("%s was %s by an environmental hazard.\n");
break;
@ -1864,11 +1837,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{
if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording!
G_StopMetalRecording();
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS)
target->player->score /= 2; // Halve the player's score in Chaos Mode
else
#endif
if (gametype == GT_MATCH && cv_match_scoring.value == 0 // note, no team match suicide penalty
&& ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player)))
{ // Suicide penalty
@ -1896,39 +1864,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{
INT32 score = 0;
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS)
{
if ((target->flags & MF_ENEMY)
&& !(target->flags & MF_MISSILE))
source->player->scoreadd++;
switch (target->type)
{
case MT_BLUECRAWLA:
case MT_GOOMBA:
score = 100*source->player->scoreadd;
break;
case MT_REDCRAWLA:
case MT_BLUEGOOMBA:
score = 150*source->player->scoreadd;
break;
case MT_JETTBOMBER:
score = 400*source->player->scoreadd;
break;
case MT_JETTGUNNER:
score = 500*source->player->scoreadd;
break;
case MT_CRAWLACOMMANDER:
score = 300*source->player->scoreadd;
break;
default:
score = 100*source->player->scoreadd;
break;
}
}
else
#endif
if (maptol & TOL_NIGHTS) // Enemies always worth 200, bosses don't do anything.
{
if ((target->flags & MF_ENEMY) && !(target->flags & (MF_MISSILE|MF_BOSS)))
@ -2089,9 +2024,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
// This determines the kind of object spawned
// during the death frame of a thing.
if (!mariomode // Don't show birds, etc. in Mario Mode Tails 12-23-2001
#ifdef CHAOSISNOTDEADYET
&& gametype != GT_CHAOS // Or Chaos Mode!
#endif
&& target->flags & MF_ENEMY)
{
if (cv_soniccd.value)
@ -2512,11 +2444,7 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
return false;
// In COOP/RACE/CHAOS, you can't hurt other players unless cv_friendlyfire is on
if (!cv_friendlyfire.value && (G_PlatformGametype()
#ifdef CHAOSISNOTDEADYET
|| gametype == GT_CHAOS
#endif
))
if (!cv_friendlyfire.value && (G_PlatformGametype()))
return false;
// Tag handling
@ -2843,17 +2771,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (target->health > 1)
{
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS && source && source->player)
{
player = source->player;
if (!((player->pflags & PF_USEDOWN) && player->dashspeed
&& (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING)))
player->scoreadd++;
P_AddPlayerScore(player, 300*player->scoreadd);
}
#endif
if (target->info->painsound)
S_StartSound(target, target->info->painsound);
@ -2882,14 +2799,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (target->health > 1)
target->flags2 |= MF2_FRET;
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS && source && source->player)
{
source->player->scoreadd++;
P_AddPlayerScore(source->player, 300*source->player->scoreadd);
}
#endif
}
#ifdef HAVE_BLUA
else if (target->flags & MF_ENEMY)

View File

@ -144,7 +144,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives);
UINT8 P_GetNextEmerald(void);
void P_GiveEmerald(boolean spawnObj);
void P_ResetScore(player_t *player);
boolean P_MenuActivePause(void);
boolean P_AutoPause(void);
void P_DoJumpShield(player_t *player);
void P_BlackOw(player_t *player);

View File

@ -1354,6 +1354,133 @@ static void P_SceneryXYMovement(mobj_t *mo)
P_SceneryXYFriction(mo, oldx, oldy);
}
//
// P_AdjustMobjFloorZ_FFloors
//
// Utility function for P_ZMovement and related
// Adjusts mo->floorz/mo->ceiling accordingly for FFloors
//
// "motype" determines what behaviour to use exactly
// This is to keep things consistent in case these various object types NEED to be different
//
// motype options:
// 0 - normal
// 1 - forces false check for water (rings)
// 2 - forces false check for water + different quicksand behaviour (scenery)
//
static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype)
{
ffloor_t *rover;
fixed_t delta1, delta2, thingtop;
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
thingtop = mo->z + mo->height;
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue;
if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected
;
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
continue;
else if (rover->flags & FF_QUICKSAND) // quicksand
;
else if (!((rover->flags & FF_BLOCKPLAYER && mo->player) // solid to players?
|| (rover->flags & FF_BLOCKOTHERS && !mo->player))) // solid to others?
continue;
if (rover->flags & FF_QUICKSAND)
{
switch (motype)
{
case 2: // scenery does things differently for some reason
if (mo->z < *rover->topheight && *rover->bottomheight < thingtop)
{
mo->floorz = mo->z;
continue;
}
break;
default:
if (mo->z < *rover->topheight && *rover->bottomheight < thingtop)
{
if (mo->floorz < mo->z)
mo->floorz = mo->z;
}
continue; // This is so you can jump/spring up through quicksand from below.
}
}
delta1 = mo->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
if (*rover->topheight > mo->floorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM))
{
mo->floorz = *rover->topheight;
}
if (*rover->bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
&& !(rover->flags & FF_PLATFORM))
{
mo->ceilingz = *rover->bottomheight;
}
}
}
//
// P_AdjustMobjFloorZ_PolyObjs
//
// Utility function for P_ZMovement and related
// Adjusts mo->floorz/mo->ceiling accordingly for PolyObjs
//
static void P_AdjustMobjFloorZ_PolyObjs(mobj_t *mo, subsector_t *subsec)
{
polyobj_t *po = subsec->polyList;
sector_t *polysec;
fixed_t delta1, delta2, thingtop;
fixed_t polytop, polybottom;
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
thingtop = mo->z + mo->height;
while(po)
{
if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID))
{
po = (polyobj_t *)(po->link.next);
continue;
}
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
if (po->flags & POF_CLIPPLANES)
{
polytop = polysec->ceilingheight;
polybottom = polysec->floorheight;
}
else
{
polytop = INT32_MAX;
polybottom = INT32_MIN;
}
delta1 = mo->z - (polybottom + ((polytop - polybottom)/2));
delta2 = thingtop - (polybottom + ((polytop - polybottom)/2));
if (polytop > mo->floorz && abs(delta1) < abs(delta2))
mo->floorz = polytop;
if (polybottom < mo->ceilingz && abs(delta1) >= abs(delta2))
mo->ceilingz = polybottom;
po = (polyobj_t *)(po->link.next);
}
}
static void P_RingZMovement(mobj_t *mo)
{
I_Assert(mo != NULL);
@ -1361,43 +1488,9 @@ static void P_RingZMovement(mobj_t *mo)
// Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors)
{
ffloor_t *rover;
fixed_t delta1, delta2;
INT32 thingtop = mo->z + mo->height;
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue;
if ((!(rover->flags & FF_BLOCKOTHERS || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue;
if (rover->flags & FF_QUICKSAND)
{
if (mo->z < *rover->topheight && *rover->bottomheight < thingtop)
{
if (mo->floorz < mo->z)
mo->floorz = mo->z;
}
continue;
}
delta1 = mo->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
if (*rover->topheight > mo->floorz && abs(delta1) < abs(delta2)
&& (!(rover->flags & FF_REVERSEPLATFORM)))
{
mo->floorz = *rover->topheight;
}
if (*rover->bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
&& (/*mo->z + mo->height <= *rover->bottomheight ||*/ !(rover->flags & FF_PLATFORM)))
{
mo->ceilingz = *rover->bottomheight;
}
}
}
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 1);
if (mo->subsector->polyList)
P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
// adjust height
if (mo->pmomz && mo->z != mo->floorz)
@ -1443,7 +1536,7 @@ boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover)
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
if ((rover->flags & FF_SWIMMABLE) && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
&& !(rover->master->flags & ML_BLOCKMONSTERS)
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > *rover->topheight - FixedMul(16*FRACUNIT, mo->scale)))
return true;
@ -1464,55 +1557,9 @@ static boolean P_ZMovement(mobj_t *mo)
// Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors)
{
ffloor_t *rover;
fixed_t delta1, delta2, thingtop = mo->z + mo->height;
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
{
#if 0 // I question the utility of having four seperate z movement functions.
if (!(rover->flags & FF_EXISTS)
|| (!((((rover->flags & FF_BLOCKPLAYER) && mo->player)
|| ((rover->flags & FF_BLOCKOTHERS) && !mo->player)) || rover->flags & FF_QUICKSAND)
|| (rover->flags & FF_SWIMMABLE)))
{
continue;
}
#else
if (!(rover->flags & FF_EXISTS))
continue;
if (mo->player && P_CheckSolidLava(mo, rover)) // only the player should be affected
;
else if (!((((rover->flags & FF_BLOCKPLAYER) && mo->player)
|| ((rover->flags & FF_BLOCKOTHERS) && !mo->player))
|| rover->flags & FF_QUICKSAND))
continue;
#endif
if (rover->flags & FF_QUICKSAND)
{
if (mo->z < *rover->topheight && *rover->bottomheight < thingtop)
{
if (mo->floorz < mo->z)
mo->floorz = mo->z;
}
continue;
}
delta1 = mo->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
if (*rover->topheight > mo->floorz && abs(delta1) < abs(delta2)
&& (!(rover->flags & FF_REVERSEPLATFORM)))
{
mo->floorz = *rover->topheight;
}
if (*rover->bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
&& (/*mo->z + mo->height <= *rover->bottomheight ||*/ !(rover->flags & FF_PLATFORM)))
{
mo->ceilingz = *rover->bottomheight;
}
}
}
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
if (mo->subsector->polyList)
P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
// adjust height
if (mo->pmomz && mo->z != mo->floorz)
@ -1922,45 +1969,9 @@ static void P_PlayerZMovement(mobj_t *mo)
// Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors)
{
ffloor_t *rover;
fixed_t delta1, delta2;
INT32 thingtop = mo->z + mo->height;
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue;
if (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))
;
else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND))
continue;
if (rover->flags & FF_QUICKSAND)
{
if (mo->z < *rover->topheight && *rover->bottomheight < thingtop)
{
if (mo->floorz < mo->z)
mo->floorz = mo->z;
}
continue; // This is so you can jump/spring up through quicksand from below.
}
delta1 = mo->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
if (*rover->topheight > mo->floorz && abs(delta1) < abs(delta2)
&& (!(rover->flags & FF_REVERSEPLATFORM)))
{
mo->floorz = *rover->topheight;
}
if (*rover->bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
&& (/*mo->z + mo->height <= *rover->bottomheight ||*/ !(rover->flags & FF_PLATFORM)))
{
mo->ceilingz = *rover->bottomheight;
}
}
}
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
if (mo->subsector->polyList)
P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
// check for smooth step up
if ((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height > mo->ceilingz)
@ -2052,26 +2063,24 @@ static void P_PlayerZMovement(mobj_t *mo)
while(po)
{
if (!P_MobjInsidePolyobj(po, mo))
{
po = (polyobj_t *)(po->link.next);
continue;
}
polysec = po->lines[0]->backsector;
// Moving polyobjects should act like conveyors if the player lands on one. (I.E. none of the momentum cut thing below) -Red
if ((mo->z == polysec->ceilingheight || mo->z+mo->height == polysec->floorheight) && (po->flags & POF_SOLID) && po->thinker)
stopmovecut = true;
if (!(po->flags & POF_LDEXEC)
|| !(po->flags & POF_SOLID))
if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID))
{
po = (polyobj_t *)(po->link.next);
continue;
}
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
// Moving polyobjects should act like conveyors if the player lands on one. (I.E. none of the momentum cut thing below) -Red
if ((mo->z == polysec->ceilingheight || mo->z+mo->height == polysec->floorheight) && po->thinker)
stopmovecut = true;
if (!(po->flags & POF_LDEXEC))
{
po = (polyobj_t *)(po->link.next);
continue;
}
if (mo->z == polysec->ceilingheight)
{
@ -2241,42 +2250,9 @@ static boolean P_SceneryZMovement(mobj_t *mo)
{
// Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors)
{
ffloor_t *rover;
fixed_t delta1, delta2;
INT32 thingtop = mo->z + mo->height;
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue;
if ((!(rover->flags & FF_BLOCKOTHERS || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue;
if (rover->flags & FF_QUICKSAND)
{
if (mo->z < *rover->topheight && *rover->bottomheight < thingtop)
{
mo->floorz = mo->z;
continue;
}
}
delta1 = mo->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
if (*rover->topheight > mo->floorz && abs(delta1) < abs(delta2)
&& (!(rover->flags & FF_REVERSEPLATFORM)))
{
mo->floorz = *rover->topheight;
}
if (*rover->bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
&& (/*mo->z + mo->height <= *rover->bottomheight ||*/ !(rover->flags & FF_PLATFORM)))
{
mo->ceilingz = *rover->bottomheight;
}
}
}
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 2);
if (mo->subsector->polyList)
P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
// adjust height
if (mo->pmomz && mo->z != mo->floorz)
@ -3371,11 +3347,7 @@ static void P_Boss2Thinker(mobj_t *mobj)
if (!mobj->movecount)
mobj->flags2 &= ~MF2_FRET;
if (!mobj->tracer
#ifdef CHAOSISNOTDEADYET
&& gametype != GT_CHAOS
#endif
)
if (!mobj->tracer)
{
var1 = 0;
A_BossJetFume(mobj);
@ -3398,11 +3370,7 @@ static void P_Boss2Thinker(mobj_t *mobj)
return;
}
if (mobj->state == &states[mobj->info->spawnstate] && mobj->health > mobj->info->damage
#ifdef CHAOSISNOTDEADYET
&& gametype != GT_CHAOS
#endif
)
if (mobj->state == &states[mobj->info->spawnstate] && mobj->health > mobj->info->damage)
A_Boss2Chase(mobj);
else if (mobj->health > 0 && mobj->state != &states[mobj->info->painstate] && mobj->state != &states[mobjinfo[mobj->info->missilestate].raisestate])
{
@ -5116,32 +5084,6 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale)
}
}
// Returns true if no boss with health is in the level.
// Used for Chaos mode
#ifdef CHAOSISNOTDEADYET
static boolean P_BossDoesntExist(void)
{
thinker_t *th;
mobj_t *mo2;
// scan the thinkers
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
continue;
mo2 = (mobj_t *)th;
if (mo2->flags & MF_BOSS && mo2->health)
return false;
}
// No boss found!
return true;
}
#endif
void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on your target
{
fixed_t dist, ndist, speedmul;
@ -6130,14 +6072,6 @@ void P_MobjThinker(mobj_t *mobj)
return;
}
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS && mobj->target->health <= 0)
{
P_RemoveMobj(mobj);
return;
}
#endif
jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale));
jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale));
@ -6209,14 +6143,6 @@ void P_MobjThinker(mobj_t *mobj)
return;
}
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS && mobj->target->health <= 0)
{
P_RemoveMobj(mobj);
return;
}
#endif
jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale));
jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale));
@ -6239,13 +6165,6 @@ void P_MobjThinker(mobj_t *mobj)
return;
}
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS && mobj->target->health <= 0)
{
P_RemoveMobj(mobj);
return;
}
#endif
P_UnsetThingPosition(mobj);
mobj->x = mobj->target->x;
mobj->y = mobj->target->y;
@ -6677,148 +6596,6 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
}
P_RemoveMobj(mobj); // make sure they disappear
return;
case MT_CHAOSSPAWNER: // Chaos Mode spawner thingy
{
// 8 enemies: Blue Crawla, Red Crawla, Crawla Commander,
// Jett-Synn Bomber, Jett-Synn Gunner, Skim,
// Egg Mobile, Egg Slimer.
// Max. 3 chances per enemy.
#ifdef CHAOSISNOTDEADYET
mobjtype_t spawnchance[8*3], enemy;
mobj_t *spawnedmo;
INT32 i = 0, numchoices = 0, stop;
fixed_t sfloorz, space, airspace, spawnz[8*3];
sfloorz = mobj->floorz;
space = mobj->ceilingz - sfloorz;
// This makes the assumption there is no gravity-defying water.
// A fair assumption to make, if you ask me.
airspace = min(space, mobj->ceilingz - mobj->watertop);
mobj->fuse = cv_chaos_spawnrate.value*TICRATE;
prandom = P_Random(); // Gotta love those random numbers!
if (cv_chaos_bluecrawla.value && space >= mobjinfo[MT_BLUECRAWLA].height)
{
stop = i + cv_chaos_bluecrawla.value;
for (; i < stop; i++)
{
spawnchance[i] = MT_BLUECRAWLA;
spawnz[i] = sfloorz;
numchoices++;
}
}
if (cv_chaos_redcrawla.value && space >= mobjinfo[MT_REDCRAWLA].height)
{
stop = i + cv_chaos_redcrawla.value;
for (; i < stop; i++)
{
spawnchance[i] = MT_REDCRAWLA;
spawnz[i] = sfloorz;
numchoices++;
}
}
if (cv_chaos_crawlacommander.value
&& space >= mobjinfo[MT_CRAWLACOMMANDER].height + 33*FRACUNIT)
{
stop = i + cv_chaos_crawlacommander.value;
for (; i < stop; i++)
{
spawnchance[i] = MT_CRAWLACOMMANDER;
spawnz[i] = sfloorz + 33*FRACUNIT;
numchoices++;
}
}
if (cv_chaos_jettysynbomber.value
&& airspace >= mobjinfo[MT_JETTBOMBER].height + 33*FRACUNIT)
{
stop = i + cv_chaos_jettysynbomber.value;
for (; i < stop; i++)
{
spawnchance[i] = MT_JETTBOMBER;
spawnz[i] = max(sfloorz, mobj->watertop) + 33*FRACUNIT;
numchoices++;
}
}
if (cv_chaos_jettysyngunner.value
&& airspace >= mobjinfo[MT_JETTGUNNER].height + 33*FRACUNIT)
{
stop = i + cv_chaos_jettysyngunner.value;
for (; i < stop; i++)
{
spawnchance[i] = MT_JETTGUNNER;
spawnz[i] = max(sfloorz, mobj->watertop) + 33*FRACUNIT;
numchoices++;
}
}
if (cv_chaos_skim.value
&& mobj->watertop < mobj->ceilingz - mobjinfo[MT_SKIM].height
&& mobj->watertop - sfloorz > mobjinfo[MT_SKIM].height/2)
{
stop = i + cv_chaos_skim.value;
for (; i < stop; i++)
{
spawnchance[i] = MT_SKIM;
spawnz[i] = mobj->watertop;
numchoices++;
}
}
if (P_BossDoesntExist())
{
if (cv_chaos_eggmobile1.value
&& space >= mobjinfo[MT_EGGMOBILE].height + 33*FRACUNIT)
{
stop = i + cv_chaos_eggmobile1.value;
for (; i < stop; i++)
{
spawnchance[i] = MT_EGGMOBILE;
spawnz[i] = sfloorz + 33*FRACUNIT;
numchoices++;
}
}
if (cv_chaos_eggmobile2.value
&& space >= mobjinfo[MT_EGGMOBILE2].height + 33*FRACUNIT)
{
stop = i + cv_chaos_eggmobile2.value;
for (; i < stop; i++)
{
spawnchance[i] = MT_EGGMOBILE2;
spawnz[i] = sfloorz + 33*FRACUNIT;
numchoices++;
}
}
}
if (numchoices)
{
fixed_t fogz;
i = prandom % numchoices;
enemy = spawnchance[i];
fogz = spawnz[i] - 32*FRACUNIT;
if (fogz < sfloorz)
fogz = sfloorz;
spawnedmo = P_SpawnMobj(mobj->x, mobj->y, spawnz[i], enemy);
P_SpawnMobj(mobj->x, mobj->y, fogz, MT_TFOG);
P_SupermanLook4Players(spawnedmo);
if (spawnedmo->target && spawnedmo->type != MT_SKIM)
P_SetMobjState(spawnedmo, spawnedmo->info->seestate);
if (spawnedmo->flags & MF_BOSS)
{
spawnedmo->flags2 |= MF2_CHAOSBOSS;
spawnedmo->momx = spawnedmo->momy = 0;
}
}
#endif
break;
}
case MT_METALSONIC_BATTLE:
break; // don't remove
case MT_SPIKE:
@ -8178,7 +7955,8 @@ void P_SpawnMapThing(mapthing_t *mthing)
if (i == NUMMOBJTYPES)
{
if (mthing->type == 3328) // 3D Mode start Thing
if (mthing->type == 3328 // 3D Mode start Thing
|| mthing->type == 750) // Chaos mode spawn
return;
CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y);
i = MT_UNKNOWN;
@ -8597,15 +8375,6 @@ ML_NOCLIMB : Direction not controllable
if (mthing->angle > 0)
mobj->health = mthing->angle;
break;
case MT_CHAOSSPAWNER:
#ifndef CHAOSISNOTDEADYET
return;
#else
if (gametype != GT_CHAOS)
return;
mobj->fuse = P_Random()*2;
break;
#endif
case MT_TRAPGOYLE:
case MT_TRAPGOYLEUP:
case MT_TRAPGOYLEDOWN:

View File

@ -43,6 +43,16 @@
#define FF_TRANSMASK 0xf0000
/// \brief shift for FF_TRANSMASK
#define FF_TRANSSHIFT 16
/// \brief preshifted translucency flags
#define FF_TRANS10 (tr_trans10<<FF_TRANSSHIFT)
#define FF_TRANS20 (tr_trans20<<FF_TRANSSHIFT)
#define FF_TRANS30 (tr_trans30<<FF_TRANSSHIFT)
#define FF_TRANS40 (tr_trans40<<FF_TRANSSHIFT)
#define FF_TRANS50 (tr_trans50<<FF_TRANSSHIFT)
#define FF_TRANS60 (tr_trans60<<FF_TRANSSHIFT)
#define FF_TRANS70 (tr_trans70<<FF_TRANSSHIFT)
#define FF_TRANS80 (tr_trans80<<FF_TRANSSHIFT)
#define FF_TRANS90 (tr_trans90<<FF_TRANSSHIFT)
/** \brief translucency tables

View File

@ -990,6 +990,241 @@ static inline UINT32 SavePlayer(const player_t *player)
return 0xFFFFFFFF;
}
//
// SaveMobjThinker
//
// Saves a mobj_t thinker
//
static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
{
const mobj_t *mobj = (const mobj_t *)th;
UINT32 diff;
UINT16 diff2;
// Ignore stationary hoops - these will be respawned from mapthings.
if (mobj->type == MT_HOOP)
return;
// These are NEVER saved.
if (mobj->type == MT_HOOPCOLLIDE)
return;
// This hoop has already been collected.
if (mobj->type == MT_HOOPCENTER && mobj->threshold == 4242)
return;
if (mobj->spawnpoint && mobj->info->doomednum != -1)
{
// spawnpoint is not modified but we must save it since it is an identifier
diff = MD_SPAWNPOINT;
if ((mobj->x != mobj->spawnpoint->x << FRACBITS) ||
(mobj->y != mobj->spawnpoint->y << FRACBITS) ||
(mobj->angle != FixedAngle(mobj->spawnpoint->angle*FRACUNIT)))
diff |= MD_POS;
if (mobj->info->doomednum != mobj->spawnpoint->type)
diff |= MD_TYPE;
}
else
diff = MD_POS | MD_TYPE; // not a map spawned thing so make it from scratch
diff2 = 0;
// not the default but the most probable
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
diff |= MD_MOM;
if (mobj->radius != mobj->info->radius)
diff |= MD_RADIUS;
if (mobj->height != mobj->info->height)
diff |= MD_HEIGHT;
if (mobj->flags != mobj->info->flags)
diff |= MD_FLAGS;
if (mobj->flags2)
diff |= MD_FLAGS2;
if (mobj->health != mobj->info->spawnhealth)
diff |= MD_HEALTH;
if (mobj->reactiontime != mobj->info->reactiontime)
diff |= MD_RTIME;
if ((statenum_t)(mobj->state-states) != mobj->info->spawnstate)
diff |= MD_STATE;
if (mobj->tics != mobj->state->tics)
diff |= MD_TICS;
if (mobj->sprite != mobj->state->sprite)
diff |= MD_SPRITE;
if (mobj->frame != mobj->state->frame)
diff |= MD_FRAME;
if (mobj->eflags)
diff |= MD_EFLAGS;
if (mobj->player)
diff |= MD_PLAYER;
if (mobj->movedir)
diff |= MD_MOVEDIR;
if (mobj->movecount)
diff |= MD_MOVECOUNT;
if (mobj->threshold)
diff |= MD_THRESHOLD;
if (mobj->lastlook != -1)
diff |= MD_LASTLOOK;
if (mobj->target)
diff |= MD_TARGET;
if (mobj->tracer)
diff |= MD_TRACER;
if (mobj->friction != ORIG_FRICTION)
diff |= MD_FRICTION;
if (mobj->movefactor != ORIG_FRICTION_FACTOR)
diff |= MD_MOVEFACTOR;
if (mobj->fuse)
diff |= MD_FUSE;
if (mobj->watertop)
diff |= MD_WATERTOP;
if (mobj->waterbottom)
diff |= MD_WATERBOTTOM;
if (mobj->scale != FRACUNIT)
diff |= MD_SCALE;
if (mobj->destscale != mobj->scale)
diff |= MD_DSCALE;
if (mobj->scalespeed != FRACUNIT/12)
diff2 |= MD2_SCALESPEED;
if (mobj == redflag)
diff |= MD_REDFLAG;
if (mobj == blueflag)
diff |= MD_BLUEFLAG;
if (mobj->cusval)
diff2 |= MD2_CUSVAL;
if (mobj->cvmem)
diff2 |= MD2_CVMEM;
if (mobj->color)
diff2 |= MD2_COLOR;
if (mobj->skin)
diff2 |= MD2_SKIN;
if (mobj->extravalue1)
diff2 |= MD2_EXTVAL1;
if (mobj->extravalue2)
diff2 |= MD2_EXTVAL2;
if (mobj->hnext)
diff2 |= MD2_HNEXT;
if (mobj->hprev)
diff2 |= MD2_HPREV;
if (diff2 != 0)
diff |= MD_MORE;
// Scrap all of that. If we're a hoop center, this is ALL we're saving.
if (mobj->type == MT_HOOPCENTER)
diff = MD_SPAWNPOINT;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, diff);
if (diff & MD_MORE)
WRITEUINT16(save_p, diff2);
// save pointer, at load time we will search this pointer to reinitilize pointers
WRITEUINT32(save_p, (size_t)mobj);
WRITEFIXED(save_p, mobj->z); // Force this so 3dfloor problems don't arise.
WRITEFIXED(save_p, mobj->floorz);
WRITEFIXED(save_p, mobj->ceilingz);
if (diff & MD_SPAWNPOINT)
{
size_t z;
for (z = 0; z < nummapthings; z++)
if (&mapthings[z] == mobj->spawnpoint)
WRITEUINT16(save_p, z);
if (mobj->type == MT_HOOPCENTER)
return;
}
if (diff & MD_TYPE)
WRITEUINT32(save_p, mobj->type);
if (diff & MD_POS)
{
WRITEFIXED(save_p, mobj->x);
WRITEFIXED(save_p, mobj->y);
WRITEANGLE(save_p, mobj->angle);
}
if (diff & MD_MOM)
{
WRITEFIXED(save_p, mobj->momx);
WRITEFIXED(save_p, mobj->momy);
WRITEFIXED(save_p, mobj->momz);
}
if (diff & MD_RADIUS)
WRITEFIXED(save_p, mobj->radius);
if (diff & MD_HEIGHT)
WRITEFIXED(save_p, mobj->height);
if (diff & MD_FLAGS)
WRITEUINT32(save_p, mobj->flags);
if (diff & MD_FLAGS2)
WRITEUINT32(save_p, mobj->flags2);
if (diff & MD_HEALTH)
WRITEINT32(save_p, mobj->health);
if (diff & MD_RTIME)
WRITEINT32(save_p, mobj->reactiontime);
if (diff & MD_STATE)
WRITEUINT16(save_p, mobj->state-states);
if (diff & MD_TICS)
WRITEINT32(save_p, mobj->tics);
if (diff & MD_SPRITE)
WRITEUINT16(save_p, mobj->sprite);
if (diff & MD_FRAME)
WRITEUINT32(save_p, mobj->frame);
if (diff & MD_EFLAGS)
WRITEUINT8(save_p, mobj->eflags);
if (diff & MD_PLAYER)
WRITEUINT8(save_p, mobj->player-players);
if (diff & MD_MOVEDIR)
WRITEANGLE(save_p, mobj->movedir);
if (diff & MD_MOVECOUNT)
WRITEINT32(save_p, mobj->movecount);
if (diff & MD_THRESHOLD)
WRITEINT32(save_p, mobj->threshold);
if (diff & MD_LASTLOOK)
WRITEINT32(save_p, mobj->lastlook);
if (diff & MD_TARGET)
WRITEUINT32(save_p, mobj->target->mobjnum);
if (diff & MD_TRACER)
WRITEUINT32(save_p, mobj->tracer->mobjnum);
if (diff & MD_FRICTION)
WRITEFIXED(save_p, mobj->friction);
if (diff & MD_MOVEFACTOR)
WRITEFIXED(save_p, mobj->movefactor);
if (diff & MD_FUSE)
WRITEINT32(save_p, mobj->fuse);
if (diff & MD_WATERTOP)
WRITEFIXED(save_p, mobj->watertop);
if (diff & MD_WATERBOTTOM)
WRITEFIXED(save_p, mobj->waterbottom);
if (diff & MD_SCALE)
WRITEFIXED(save_p, mobj->scale);
if (diff & MD_DSCALE)
WRITEFIXED(save_p, mobj->destscale);
if (diff2 & MD2_SCALESPEED)
WRITEFIXED(save_p, mobj->scalespeed);
if (diff2 & MD2_CUSVAL)
WRITEINT32(save_p, mobj->cusval);
if (diff2 & MD2_CVMEM)
WRITEINT32(save_p, mobj->cvmem);
if (diff2 & MD2_SKIN)
WRITEUINT8(save_p, (UINT8)((skin_t *)mobj->skin - skins));
if (diff2 & MD2_COLOR)
WRITEUINT8(save_p, mobj->color);
if (diff2 & MD2_EXTVAL1)
WRITEINT32(save_p, mobj->extravalue1);
if (diff2 & MD2_EXTVAL2)
WRITEINT32(save_p, mobj->extravalue2);
if (diff2 & MD2_HNEXT)
WRITEUINT32(save_p, mobj->hnext->mobjnum);
if (diff2 & MD2_HPREV)
WRITEUINT32(save_p, mobj->hprev->mobjnum);
WRITEUINT32(save_p, mobj->mobjnum);
}
//
// SaveSpecialLevelThinker
//
@ -1395,9 +1630,6 @@ static inline void SaveWhatThinker(const thinker_t *th, const UINT8 type)
static void P_NetArchiveThinkers(void)
{
const thinker_t *th;
const mobj_t *mobj;
UINT32 diff;
UINT16 diff2;
WRITEUINT32(save_p, ARCHIVEBLOCK_THINKERS);
@ -1406,230 +1638,8 @@ static void P_NetArchiveThinkers(void)
{
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
{
mobj = (const mobj_t *)th;
// Ignore stationary hoops - these will be respawned from mapthings.
if (mobj->type == MT_HOOP)
continue;
// These are NEVER saved.
if (mobj->type == MT_HOOPCOLLIDE)
continue;
// This hoop has already been collected.
if (mobj->type == MT_HOOPCENTER && mobj->threshold == 4242)
continue;
if (mobj->spawnpoint && mobj->info->doomednum != -1)
{
// spawnpoint is not modified but we must save it since it is an identifier
diff = MD_SPAWNPOINT;
if ((mobj->x != mobj->spawnpoint->x << FRACBITS) ||
(mobj->y != mobj->spawnpoint->y << FRACBITS) ||
(mobj->angle != FixedAngle(mobj->spawnpoint->angle*FRACUNIT)))
diff |= MD_POS;
if (mobj->info->doomednum != mobj->spawnpoint->type)
diff |= MD_TYPE;
}
else
diff = MD_POS | MD_TYPE; // not a map spawned thing so make it from scratch
diff2 = 0;
// not the default but the most probable
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
diff |= MD_MOM;
if (mobj->radius != mobj->info->radius)
diff |= MD_RADIUS;
if (mobj->height != mobj->info->height)
diff |= MD_HEIGHT;
if (mobj->flags != mobj->info->flags)
diff |= MD_FLAGS;
if (mobj->flags2)
diff |= MD_FLAGS2;
if (mobj->health != mobj->info->spawnhealth)
diff |= MD_HEALTH;
if (mobj->reactiontime != mobj->info->reactiontime)
diff |= MD_RTIME;
if ((statenum_t)(mobj->state-states) != mobj->info->spawnstate)
diff |= MD_STATE;
if (mobj->tics != mobj->state->tics)
diff |= MD_TICS;
if (mobj->sprite != mobj->state->sprite)
diff |= MD_SPRITE;
if (mobj->frame != mobj->state->frame)
diff |= MD_FRAME;
if (mobj->eflags)
diff |= MD_EFLAGS;
if (mobj->player)
diff |= MD_PLAYER;
if (mobj->movedir)
diff |= MD_MOVEDIR;
if (mobj->movecount)
diff |= MD_MOVECOUNT;
if (mobj->threshold)
diff |= MD_THRESHOLD;
if (mobj->lastlook != -1)
diff |= MD_LASTLOOK;
if (mobj->target)
diff |= MD_TARGET;
if (mobj->tracer)
diff |= MD_TRACER;
if (mobj->friction != ORIG_FRICTION)
diff |= MD_FRICTION;
if (mobj->movefactor != ORIG_FRICTION_FACTOR)
diff |= MD_MOVEFACTOR;
if (mobj->fuse)
diff |= MD_FUSE;
if (mobj->watertop)
diff |= MD_WATERTOP;
if (mobj->waterbottom)
diff |= MD_WATERBOTTOM;
if (mobj->scale != FRACUNIT)
diff |= MD_SCALE;
if (mobj->destscale != mobj->scale)
diff |= MD_DSCALE;
if (mobj->scalespeed != FRACUNIT/12)
diff2 |= MD2_SCALESPEED;
if (mobj == redflag)
diff |= MD_REDFLAG;
if (mobj == blueflag)
diff |= MD_BLUEFLAG;
if (mobj->cusval)
diff2 |= MD2_CUSVAL;
if (mobj->cvmem)
diff2 |= MD2_CVMEM;
if (mobj->color)
diff2 |= MD2_COLOR;
if (mobj->skin)
diff2 |= MD2_SKIN;
if (mobj->extravalue1)
diff2 |= MD2_EXTVAL1;
if (mobj->extravalue2)
diff2 |= MD2_EXTVAL2;
if (mobj->hnext)
diff2 |= MD2_HNEXT;
if (mobj->hprev)
diff2 |= MD2_HPREV;
if (diff2 != 0)
diff |= MD_MORE;
// Scrap all of that. If we're a hoop center, this is ALL we're saving.
if (mobj->type == MT_HOOPCENTER)
diff = MD_SPAWNPOINT;
WRITEUINT8(save_p, tc_mobj);
WRITEUINT32(save_p, diff);
if (diff & MD_MORE)
WRITEUINT16(save_p, diff2);
// save pointer, at load time we will search this pointer to reinitilize pointers
WRITEUINT32(save_p, (size_t)mobj);
WRITEFIXED(save_p, mobj->z); // Force this so 3dfloor problems don't arise.
WRITEFIXED(save_p, mobj->floorz);
WRITEFIXED(save_p, mobj->ceilingz);
if (diff & MD_SPAWNPOINT)
{
size_t z;
for (z = 0; z < nummapthings; z++)
if (&mapthings[z] == mobj->spawnpoint)
WRITEUINT16(save_p, z);
if (mobj->type == MT_HOOPCENTER)
continue;
}
if (diff & MD_TYPE)
WRITEUINT32(save_p, mobj->type);
if (diff & MD_POS)
{
WRITEFIXED(save_p, mobj->x);
WRITEFIXED(save_p, mobj->y);
WRITEANGLE(save_p, mobj->angle);
}
if (diff & MD_MOM)
{
WRITEFIXED(save_p, mobj->momx);
WRITEFIXED(save_p, mobj->momy);
WRITEFIXED(save_p, mobj->momz);
}
if (diff & MD_RADIUS)
WRITEFIXED(save_p, mobj->radius);
if (diff & MD_HEIGHT)
WRITEFIXED(save_p, mobj->height);
if (diff & MD_FLAGS)
WRITEUINT32(save_p, mobj->flags);
if (diff & MD_FLAGS2)
WRITEUINT32(save_p, mobj->flags2);
if (diff & MD_HEALTH)
WRITEINT32(save_p, mobj->health);
if (diff & MD_RTIME)
WRITEINT32(save_p, mobj->reactiontime);
if (diff & MD_STATE)
WRITEUINT16(save_p, mobj->state-states);
if (diff & MD_TICS)
WRITEINT32(save_p, mobj->tics);
if (diff & MD_SPRITE)
WRITEUINT16(save_p, mobj->sprite);
if (diff & MD_FRAME)
WRITEUINT32(save_p, mobj->frame);
if (diff & MD_EFLAGS)
WRITEUINT8(save_p, mobj->eflags);
if (diff & MD_PLAYER)
WRITEUINT8(save_p, mobj->player-players);
if (diff & MD_MOVEDIR)
WRITEANGLE(save_p, mobj->movedir);
if (diff & MD_MOVECOUNT)
WRITEINT32(save_p, mobj->movecount);
if (diff & MD_THRESHOLD)
WRITEINT32(save_p, mobj->threshold);
if (diff & MD_LASTLOOK)
WRITEINT32(save_p, mobj->lastlook);
if (diff & MD_TARGET)
WRITEUINT32(save_p, mobj->target->mobjnum);
if (diff & MD_TRACER)
WRITEUINT32(save_p, mobj->tracer->mobjnum);
if (diff & MD_FRICTION)
WRITEFIXED(save_p, mobj->friction);
if (diff & MD_MOVEFACTOR)
WRITEFIXED(save_p, mobj->movefactor);
if (diff & MD_FUSE)
WRITEINT32(save_p, mobj->fuse);
if (diff & MD_WATERTOP)
WRITEFIXED(save_p, mobj->watertop);
if (diff & MD_WATERBOTTOM)
WRITEFIXED(save_p, mobj->waterbottom);
if (diff & MD_SCALE)
WRITEFIXED(save_p, mobj->scale);
if (diff & MD_DSCALE)
WRITEFIXED(save_p, mobj->destscale);
if (diff2 & MD2_SCALESPEED)
WRITEFIXED(save_p, mobj->scalespeed);
if (diff2 & MD2_CUSVAL)
WRITEINT32(save_p, mobj->cusval);
if (diff2 & MD2_CVMEM)
WRITEINT32(save_p, mobj->cvmem);
if (diff2 & MD2_SKIN)
WRITEUINT8(save_p, (UINT8)((skin_t *)mobj->skin - skins));
if (diff2 & MD2_COLOR)
WRITEUINT8(save_p, mobj->color);
if (diff2 & MD2_EXTVAL1)
WRITEINT32(save_p, mobj->extravalue1);
if (diff2 & MD2_EXTVAL2)
WRITEINT32(save_p, mobj->extravalue2);
if (diff2 & MD2_HNEXT)
WRITEUINT32(save_p, mobj->hnext->mobjnum);
if (diff2 & MD2_HPREV)
WRITEUINT32(save_p, mobj->hprev->mobjnum);
WRITEUINT32(save_p, mobj->mobjnum);
SaveMobjThinker(th, tc_mobj);
continue;
}
#ifdef PARANOIA
else if (th->function.acp1 == (actionf_p1)P_RainThinker
@ -1862,6 +1872,232 @@ static inline player_t *LoadPlayer(UINT32 player)
return &players[player];
}
//
// LoadMobjThinker
//
// Loads a mobj_t from a save game
//
static void LoadMobjThinker(actionf_p1 thinker)
{
thinker_t *next;
mobj_t *mobj;
UINT32 diff;
UINT16 diff2;
INT32 i;
fixed_t z, floorz, ceilingz;
diff = READUINT32(save_p);
if (diff & MD_MORE)
diff2 = READUINT16(save_p);
else
diff2 = 0;
next = (void *)(size_t)READUINT32(save_p);
z = READFIXED(save_p); // Force this so 3dfloor problems don't arise.
floorz = READFIXED(save_p);
ceilingz = READFIXED(save_p);
if (diff & MD_SPAWNPOINT)
{
UINT16 spawnpointnum = READUINT16(save_p);
if (mapthings[spawnpointnum].type == 1705 || mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case
{
P_SpawnHoopsAndRings(&mapthings[spawnpointnum]);
return;
}
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
mobj->spawnpoint = &mapthings[spawnpointnum];
mapthings[spawnpointnum].mobj = mobj;
}
else
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
// declare this as a valid mobj as soon as possible.
mobj->thinker.function.acp1 = thinker;
mobj->z = z;
mobj->floorz = floorz;
mobj->ceilingz = ceilingz;
if (diff & MD_TYPE)
mobj->type = READUINT32(save_p);
else
{
for (i = 0; i < NUMMOBJTYPES; i++)
if (mobj->spawnpoint && mobj->spawnpoint->type == mobjinfo[i].doomednum)
break;
if (i == NUMMOBJTYPES)
{
if (mobj->spawnpoint)
CONS_Alert(CONS_ERROR, "Found mobj with unknown map thing type %d\n", mobj->spawnpoint->type);
else
CONS_Alert(CONS_ERROR, "Found mobj with unknown map thing type NULL\n");
I_Error("Savegame corrupted");
}
mobj->type = i;
}
mobj->info = &mobjinfo[mobj->type];
if (diff & MD_POS)
{
mobj->x = READFIXED(save_p);
mobj->y = READFIXED(save_p);
mobj->angle = READANGLE(save_p);
}
else
{
mobj->x = mobj->spawnpoint->x << FRACBITS;
mobj->y = mobj->spawnpoint->y << FRACBITS;
mobj->angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT);
}
if (diff & MD_MOM)
{
mobj->momx = READFIXED(save_p);
mobj->momy = READFIXED(save_p);
mobj->momz = READFIXED(save_p);
} // otherwise they're zero, and the memset took care of it
if (diff & MD_RADIUS)
mobj->radius = READFIXED(save_p);
else
mobj->radius = mobj->info->radius;
if (diff & MD_HEIGHT)
mobj->height = READFIXED(save_p);
else
mobj->height = mobj->info->height;
if (diff & MD_FLAGS)
mobj->flags = READUINT32(save_p);
else
mobj->flags = mobj->info->flags;
if (diff & MD_FLAGS2)
mobj->flags2 = READUINT32(save_p);
if (diff & MD_HEALTH)
mobj->health = READINT32(save_p);
else
mobj->health = mobj->info->spawnhealth;
if (diff & MD_RTIME)
mobj->reactiontime = READINT32(save_p);
else
mobj->reactiontime = mobj->info->reactiontime;
if (diff & MD_STATE)
mobj->state = &states[READUINT16(save_p)];
else
mobj->state = &states[mobj->info->spawnstate];
if (diff & MD_TICS)
mobj->tics = READINT32(save_p);
else
mobj->tics = mobj->state->tics;
if (diff & MD_SPRITE)
mobj->sprite = READUINT16(save_p);
else
mobj->sprite = mobj->state->sprite;
if (diff & MD_FRAME)
mobj->frame = READUINT32(save_p);
else
mobj->frame = mobj->state->frame;
if (diff & MD_EFLAGS)
mobj->eflags = READUINT8(save_p);
if (diff & MD_PLAYER)
{
i = READUINT8(save_p);
mobj->player = &players[i];
mobj->player->mo = mobj;
// added for angle prediction
if (consoleplayer == i)
localangle = mobj->angle;
if (secondarydisplayplayer == i)
localangle2 = mobj->angle;
}
if (diff & MD_MOVEDIR)
mobj->movedir = READANGLE(save_p);
if (diff & MD_MOVECOUNT)
mobj->movecount = READINT32(save_p);
if (diff & MD_THRESHOLD)
mobj->threshold = READINT32(save_p);
if (diff & MD_LASTLOOK)
mobj->lastlook = READINT32(save_p);
else
mobj->lastlook = -1;
if (diff & MD_TARGET)
mobj->target = (mobj_t *)(size_t)READUINT32(save_p);
if (diff & MD_TRACER)
mobj->tracer = (mobj_t *)(size_t)READUINT32(save_p);
if (diff & MD_FRICTION)
mobj->friction = READFIXED(save_p);
else
mobj->friction = ORIG_FRICTION;
if (diff & MD_MOVEFACTOR)
mobj->movefactor = READFIXED(save_p);
else
mobj->movefactor = ORIG_FRICTION_FACTOR;
if (diff & MD_FUSE)
mobj->fuse = READINT32(save_p);
if (diff & MD_WATERTOP)
mobj->watertop = READFIXED(save_p);
if (diff & MD_WATERBOTTOM)
mobj->waterbottom = READFIXED(save_p);
if (diff & MD_SCALE)
mobj->scale = READFIXED(save_p);
else
mobj->scale = FRACUNIT;
if (diff & MD_DSCALE)
mobj->destscale = READFIXED(save_p);
else
mobj->destscale = mobj->scale;
if (diff2 & MD2_SCALESPEED)
mobj->scalespeed = READFIXED(save_p);
else
mobj->scalespeed = FRACUNIT/12;
if (diff2 & MD2_CUSVAL)
mobj->cusval = READINT32(save_p);
if (diff2 & MD2_CVMEM)
mobj->cvmem = READINT32(save_p);
if (diff2 & MD2_SKIN)
mobj->skin = &skins[READUINT8(save_p)];
if (diff2 & MD2_COLOR)
mobj->color = READUINT8(save_p);
if (diff2 & MD2_EXTVAL1)
mobj->extravalue1 = READINT32(save_p);
if (diff2 & MD2_EXTVAL2)
mobj->extravalue2 = READINT32(save_p);
if (diff2 & MD2_HNEXT)
mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_HPREV)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
if (diff & MD_REDFLAG)
{
redflag = mobj;
rflagpoint = mobj->spawnpoint;
}
if (diff & MD_BLUEFLAG)
{
blueflag = mobj;
bflagpoint = mobj->spawnpoint;
}
// set sprev, snext, bprev, bnext, subsector
P_SetThingPosition(mobj);
mobj->mobjnum = READUINT32(save_p);
if (mobj->player)
{
if (mobj->eflags & MFE_VERTICALFLIP)
mobj->player->viewz = mobj->z + mobj->height - mobj->player->viewheight;
else
mobj->player->viewz = mobj->player->mo->z + mobj->player->viewheight;
}
P_AddThinker(&mobj->thinker);
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
}
//
// LoadSpecialLevelThinker
//
@ -2131,11 +2367,15 @@ static void LoadPusherThinker(actionf_p1 thinker)
static inline void LoadLaserThinker(actionf_p1 thinker)
{
laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ffloor_t *rover = NULL;
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->ffloor = NULL;
ht->sec = LoadSector(READUINT32(save_p));
ht->sourceline = LoadLine(READUINT32(save_p));
for (rover = ht->sector->ffloors; rover; rover = rover->next)
if (rover->secnum == (size_t)(ht->sec - sectors)
&& rover->master == ht->sourceline)
ht->ffloor = rover;
P_AddThinker(&ht->thinker);
}
@ -2333,13 +2573,8 @@ static void P_NetUnArchiveThinkers(void)
{
thinker_t *currentthinker;
thinker_t *next;
mobj_t *mobj;
UINT32 diff;
UINT16 diff2;
INT32 i;
UINT8 tclass;
UINT8 restoreNum = false;
fixed_t z, floorz, ceilingz;
if (READUINT32(save_p) != ARCHIVEBLOCK_THINKERS)
I_Error("Bad $$$.sav at archive block Thinkers");
@ -2350,7 +2585,6 @@ static void P_NetUnArchiveThinkers(void)
{
next = currentthinker->next;
mobj = (mobj_t *)currentthinker;
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
P_RemoveSavegameMobj((mobj_t *)currentthinker); // item isn't saved, don't remove it
else
@ -2372,216 +2606,7 @@ static void P_NetUnArchiveThinkers(void)
switch (tclass)
{
case tc_mobj:
diff = READUINT32(save_p);
if (diff & MD_MORE)
diff2 = READUINT16(save_p);
else
diff2 = 0;
next = (void *)(size_t)READUINT32(save_p);
z = READFIXED(save_p); // Force this so 3dfloor problems don't arise.
floorz = READFIXED(save_p);
ceilingz = READFIXED(save_p);
if (diff & MD_SPAWNPOINT)
{
UINT16 spawnpointnum = READUINT16(save_p);
if (mapthings[spawnpointnum].type == 1705 || mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case
{
P_SpawnHoopsAndRings(&mapthings[spawnpointnum]);
continue;
}
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
mobj->spawnpoint = &mapthings[spawnpointnum];
mapthings[spawnpointnum].mobj = mobj;
}
else
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
// declare this as a valid mobj as soon as possible.
mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
mobj->z = z;
mobj->floorz = floorz;
mobj->ceilingz = ceilingz;
if (diff & MD_TYPE)
mobj->type = READUINT32(save_p);
else
{
for (i = 0; i < NUMMOBJTYPES; i++)
if (mobj->spawnpoint && mobj->spawnpoint->type == mobjinfo[i].doomednum)
break;
if (i == NUMMOBJTYPES)
{
if (mobj->spawnpoint)
CONS_Alert(CONS_ERROR, "Found mobj with unknown map thing type %d\n", mobj->spawnpoint->type);
else
CONS_Alert(CONS_ERROR, "Found mobj with unknown map thing type NULL\n");
I_Error("Savegame corrupted");
}
mobj->type = i;
}
mobj->info = &mobjinfo[mobj->type];
if (diff & MD_POS)
{
mobj->x = READFIXED(save_p);
mobj->y = READFIXED(save_p);
mobj->angle = READANGLE(save_p);
}
else
{
mobj->x = mobj->spawnpoint->x << FRACBITS;
mobj->y = mobj->spawnpoint->y << FRACBITS;
mobj->angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT);
}
if (diff & MD_MOM)
{
mobj->momx = READFIXED(save_p);
mobj->momy = READFIXED(save_p);
mobj->momz = READFIXED(save_p);
} // otherwise they're zero, and the memset took care of it
if (diff & MD_RADIUS)
mobj->radius = READFIXED(save_p);
else
mobj->radius = mobj->info->radius;
if (diff & MD_HEIGHT)
mobj->height = READFIXED(save_p);
else
mobj->height = mobj->info->height;
if (diff & MD_FLAGS)
mobj->flags = READUINT32(save_p);
else
mobj->flags = mobj->info->flags;
if (diff & MD_FLAGS2)
mobj->flags2 = READUINT32(save_p);
if (diff & MD_HEALTH)
mobj->health = READINT32(save_p);
else
mobj->health = mobj->info->spawnhealth;
if (diff & MD_RTIME)
mobj->reactiontime = READINT32(save_p);
else
mobj->reactiontime = mobj->info->reactiontime;
if (diff & MD_STATE)
mobj->state = &states[READUINT16(save_p)];
else
mobj->state = &states[mobj->info->spawnstate];
if (diff & MD_TICS)
mobj->tics = READINT32(save_p);
else
mobj->tics = mobj->state->tics;
if (diff & MD_SPRITE)
mobj->sprite = READUINT16(save_p);
else
mobj->sprite = mobj->state->sprite;
if (diff & MD_FRAME)
mobj->frame = READUINT32(save_p);
else
mobj->frame = mobj->state->frame;
if (diff & MD_EFLAGS)
mobj->eflags = READUINT8(save_p);
if (diff & MD_PLAYER)
{
i = READUINT8(save_p);
mobj->player = &players[i];
mobj->player->mo = mobj;
// added for angle prediction
if (consoleplayer == i)
localangle = mobj->angle;
if (secondarydisplayplayer == i)
localangle2 = mobj->angle;
}
if (diff & MD_MOVEDIR)
mobj->movedir = READANGLE(save_p);
if (diff & MD_MOVECOUNT)
mobj->movecount = READINT32(save_p);
if (diff & MD_THRESHOLD)
mobj->threshold = READINT32(save_p);
if (diff & MD_LASTLOOK)
mobj->lastlook = READINT32(save_p);
else
mobj->lastlook = -1;
if (diff & MD_TARGET)
mobj->target = (mobj_t *)(size_t)READUINT32(save_p);
if (diff & MD_TRACER)
mobj->tracer = (mobj_t *)(size_t)READUINT32(save_p);
if (diff & MD_FRICTION)
mobj->friction = READFIXED(save_p);
else
mobj->friction = ORIG_FRICTION;
if (diff & MD_MOVEFACTOR)
mobj->movefactor = READFIXED(save_p);
else
mobj->movefactor = ORIG_FRICTION_FACTOR;
if (diff & MD_FUSE)
mobj->fuse = READINT32(save_p);
if (diff & MD_WATERTOP)
mobj->watertop = READFIXED(save_p);
if (diff & MD_WATERBOTTOM)
mobj->waterbottom = READFIXED(save_p);
if (diff & MD_SCALE)
mobj->scale = READFIXED(save_p);
else
mobj->scale = FRACUNIT;
if (diff & MD_DSCALE)
mobj->destscale = READFIXED(save_p);
else
mobj->destscale = mobj->scale;
if (diff2 & MD2_SCALESPEED)
mobj->scalespeed = READFIXED(save_p);
else
mobj->scalespeed = FRACUNIT/12;
if (diff2 & MD2_CUSVAL)
mobj->cusval = READINT32(save_p);
if (diff2 & MD2_CVMEM)
mobj->cvmem = READINT32(save_p);
if (diff2 & MD2_SKIN)
mobj->skin = &skins[READUINT8(save_p)];
if (diff2 & MD2_COLOR)
mobj->color = READUINT8(save_p);
if (diff2 & MD2_EXTVAL1)
mobj->extravalue1 = READINT32(save_p);
if (diff2 & MD2_EXTVAL2)
mobj->extravalue2 = READINT32(save_p);
if (diff2 & MD2_HNEXT)
mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_HPREV)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
if (diff & MD_REDFLAG)
{
redflag = mobj;
rflagpoint = mobj->spawnpoint;
}
if (diff & MD_BLUEFLAG)
{
blueflag = mobj;
bflagpoint = mobj->spawnpoint;
}
// set sprev, snext, bprev, bnext, subsector
P_SetThingPosition(mobj);
mobj->mobjnum = READUINT32(save_p);
if (mobj->player)
{
if (mobj->eflags & MFE_VERTICALFLIP)
mobj->player->viewz = mobj->z + mobj->height - mobj->player->viewheight;
else
mobj->player->viewz = mobj->player->mo->z + mobj->player->viewheight;
}
P_AddThinker(&mobj->thinker);
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
LoadMobjThinker((actionf_p1)P_MobjThinker);
break;
case tc_ceiling:

View File

@ -1502,22 +1502,26 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, fixed_t bx1, fixed_t by1)
{
fixed_t bx2 = bx1 + MAPBLOCKUNITS;
fixed_t by2 = by1 + MAPBLOCKUNITS;
line_t boxline, testline;
vertex_t vbox, vtest;
fixed_t bbox[4];
line_t testline;
vertex_t vtest;
bbox[BOXRIGHT] = bx1 + MAPBLOCKUNITS;
bbox[BOXTOP] = by1 + MAPBLOCKUNITS;
bbox[BOXLEFT] = bx1;
bbox[BOXBOTTOM] = by1;
// Trivial rejection
if (cx1 < bx1 && cx2 < bx1)
if (cx1 < bbox[BOXLEFT] && cx2 < bbox[BOXLEFT])
return false;
if (cx1 > bx2 && cx2 > bx2)
if (cx1 > bbox[BOXRIGHT] && cx2 > bbox[BOXRIGHT])
return false;
if (cy1 < by1 && cy2 < by1)
if (cy1 < bbox[BOXBOTTOM] && cy2 < bbox[BOXBOTTOM])
return false;
if (cy1 > by2 && cy2 > by2)
if (cy1 > bbox[BOXTOP] && cy2 > bbox[BOXTOP])
return false;
// Rats, guess we gotta check
@ -1527,12 +1531,11 @@ static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, f
cy1 <<= FRACBITS;
cx2 <<= FRACBITS;
cy2 <<= FRACBITS;
bx1 <<= FRACBITS;
by1 <<= FRACBITS;
bx2 <<= FRACBITS;
by2 <<= FRACBITS;
bbox[BOXTOP] <<= FRACBITS;
bbox[BOXBOTTOM] <<= FRACBITS;
bbox[BOXLEFT] <<= FRACBITS;
bbox[BOXRIGHT] <<= FRACBITS;
boxline.v1 = &vbox;
testline.v1 = &vtest;
testline.v1->x = cx1;
@ -1540,47 +1543,12 @@ static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, f
testline.dx = cx2 - cx1;
testline.dy = cy2 - cy1;
// Test line against bottom edge of box
boxline.v1->x = bx1;
boxline.v1->y = by1;
boxline.dx = bx2 - bx1;
boxline.dy = 0;
if ((testline.dx > 0) ^ (testline.dy > 0))
testline.slopetype = ST_NEGATIVE;
else
testline.slopetype = ST_POSITIVE;
if (P_PointOnLineSide(cx1, cy1, &boxline) != P_PointOnLineSide(cx2, cy2, &boxline)
&& P_PointOnLineSide(boxline.v1->x, boxline.v1->y, &testline) != P_PointOnLineSide(boxline.v1->x+boxline.dx, boxline.v1->y+boxline.dy, &testline))
return true;
// Right edge of box
boxline.v1->x = bx2;
boxline.v1->y = by1;
boxline.dx = 0;
boxline.dy = by2-by1;
if (P_PointOnLineSide(cx1, cy1, &boxline) != P_PointOnLineSide(cx2, cy2, &boxline)
&& P_PointOnLineSide(boxline.v1->x, boxline.v1->y, &testline) != P_PointOnLineSide(boxline.v1->x+boxline.dx, boxline.v1->y+boxline.dy, &testline))
return true;
// Top edge of box
boxline.v1->x = bx1;
boxline.v1->y = by2;
boxline.dx = bx2 - bx1;
boxline.dy = 0;
if (P_PointOnLineSide(cx1, cy1, &boxline) != P_PointOnLineSide(cx2, cy2, &boxline)
&& P_PointOnLineSide(boxline.v1->x, boxline.v1->y, &testline) != P_PointOnLineSide(boxline.v1->x+boxline.dx, boxline.v1->y+boxline.dy, &testline))
return true;
// Left edge of box
boxline.v1->x = bx1;
boxline.v1->y = by1;
boxline.dx = 0;
boxline.dy = by2-by1;
if (P_PointOnLineSide(cx1, cy1, &boxline) != P_PointOnLineSide(cx2, cy2, &boxline)
&& P_PointOnLineSide(boxline.v1->x, boxline.v1->y, &testline) != P_PointOnLineSide(boxline.v1->x+boxline.dx, boxline.v1->y+boxline.dy, &testline))
return true;
return false;
return P_BoxOnLineSide(bbox, &testline) == -1;
}
//
@ -2435,11 +2403,8 @@ boolean P_SetupLevel(boolean skipprecip)
// chasecam on in chaos, race, coop
// chasecam off in match, tag, capture the flag
chase = (gametype == GT_RACE || gametype == GT_COMPETITION || gametype == GT_COOP
#ifdef CHAOSISNOTDEADYET
|| gametype == GT_CHAOS
#endif
) || (maptol & TOL_2D);
chase = (gametype == GT_RACE || gametype == GT_COMPETITION || gametype == GT_COOP)
|| (maptol & TOL_2D);
if (!dedicated)
{

View File

@ -94,6 +94,7 @@ typedef struct
thinker_t **thinkers;
} thinkerlist_t;
static void P_SearchForDisableLinedefs(void);
static void P_SpawnScrollers(void);
static void P_SpawnFriction(void);
static void P_SpawnPushers(void);
@ -4776,6 +4777,18 @@ void P_UpdateSpecials(void)
}
}
static inline ffloor_t *P_GetFFloorBySec(sector_t *sec, sector_t *sec2)
{
ffloor_t *rover;
if (!sec->ffloors)
return NULL;
for (rover = sec->ffloors; rover; rover = rover->next)
if (rover->secnum == (size_t)(sec2 - sectors))
return rover;
return NULL;
}
/** Adds a newly formed 3Dfloor structure to a sector's ffloors list.
*
* \param sec Target sector.
@ -4822,7 +4835,9 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
size_t i;
if (sec == sec2)
return false; //Don't need a fake floor on a control sector.
return NULL; //Don't need a fake floor on a control sector.
if ((ffloor = (P_GetFFloorBySec(sec, sec2))))
return ffloor; // If this ffloor already exists, return it
if (sec2->ceilingheight < sec2->floorheight)
{
@ -5312,9 +5327,6 @@ void T_LaserFlash(laserthink_t *flash)
ffloor_t *ffloor = flash->ffloor;
sector_t *sector = flash->sector;
if (!ffloor)
flash->ffloor = ffloor = P_AddFakeFloor(sector, flash->sec, flash->sourceline, laserflags, NULL);
if (!ffloor || !(ffloor->flags & FF_EXISTS))
return;
@ -5409,6 +5421,10 @@ void P_SpawnSpecials(INT32 fromnetsave)
thinkerlist_t *secthinkers;
thinker_t *th;
// This used to be used, and *should* be used in the future,
// but currently isn't.
(void)fromnetsave;
// Set the default gravity. Custom gravity overrides this setting.
gravity = FRACUNIT/2;
@ -5480,37 +5496,12 @@ void P_SpawnSpecials(INT32 fromnetsave)
curWeather = PRECIP_NONE;
P_InitTagLists(); // Create xref tables for tags
P_SearchForDisableLinedefs(); // Disable linedefs are now allowed to disable *any* line
P_SpawnScrollers(); // Add generalized scrollers
P_SpawnFriction(); // Friction model using linedefs
P_SpawnPushers(); // Pusher model using linedefs
// Look for disable linedefs
for (i = 0; i < numlines; i++)
{
if (lines[i].special == 6)
{
// Ability flags can disable disable linedefs now, lol
if (netgame || multiplayer)
{
// future: nonet flag?
}
else if (((lines[i].flags & ML_NETONLY) != ML_NETONLY)
&& !(players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
&& !(players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
&& !(players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX )))
{
for (j = -1; (j = P_FindLineFromLineTag(&lines[i], j)) >= 0;)
{
lines[j].tag = 0;
lines[j].special = 0;
}
}
lines[i].special = 0;
lines[i].tag = 0;
}
}
// Look for thinkers that affect FOFs, and sort them by sector
secthinkers = Z_Calloc(numsectors * sizeof(thinkerlist_t), PU_STATIC, NULL);
@ -5993,12 +5984,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
break;
case 160: // Float/bob platform
sec = sides[*lines[i].sidenum].sector - sectors;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
{
P_AddFakeFloor(&sectors[s], &sectors[sec], lines + i,
FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB, secthinkers);
}
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB, secthinkers);
break;
case 170: // Crumbling platform
@ -6043,13 +6029,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
break;
case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits
sec = sides[*lines[i].sidenum].sector - sectors;
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers);
lines[i].flags |= ML_BLOCKMONSTERS;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
{
P_AddFakeFloor(&sectors[s], &sectors[sec], lines + i,
FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers);
}
P_AddOldAirbob(lines[i].frontsector, lines + i, true);
break;
@ -6061,21 +6042,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
break;
case 178: // Crumbling platform that will float when it hits water
sec = sides[*lines[i].sidenum].sector - sectors;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
{
P_AddFakeFloor(&sectors[s], &sectors[sec], lines + i,
FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CRUMBLE|FF_FLOATBOB, secthinkers);
}
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CRUMBLE|FF_FLOATBOB, secthinkers);
break;
case 179: // Crumbling platform that will float when it hits water, but not return
sec = sides[*lines[i].sidenum].sector - sectors;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
{
P_AddFakeFloor(&sectors[s], &sectors[sec], lines + i,
FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE|FF_FLOATBOB|FF_NORETURN, secthinkers);
}
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE|FF_FLOATBOB|FF_NORETURN, secthinkers);
break;
case 180: // Air bobbing platform that will crumble
@ -6158,14 +6129,13 @@ void P_SpawnSpecials(INT32 fromnetsave)
break;
case 202: // Fog
ffloorflags = FF_EXISTS|FF_RENDERALL|FF_FOG|FF_BOTHPLANES|FF_INVERTPLANES|FF_ALLSIDES|FF_INVERTSIDES|FF_CUTEXTRA|FF_EXTRA|FF_DOUBLESHADOW|FF_CUTSPRITES;
sec = sides[*lines[i].sidenum].sector - sectors;
// SoM: Because it's fog, check for an extra colormap and set
// the fog flag...
if (sectors[sec].extra_colormap)
sectors[sec].extra_colormap->fog = 1;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
P_AddFakeFloor(&sectors[s], &sectors[sec], lines + i,
FF_EXISTS|FF_RENDERALL|FF_FOG|FF_BOTHPLANES|FF_INVERTPLANES|FF_ALLSIDES|FF_INVERTSIDES|FF_CUTEXTRA|FF_EXTRA|FF_DOUBLESHADOW|FF_CUTSPRITES, secthinkers);
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
break;
case 220: // Like opaque water, but not swimmable. (Good for snow effect on FOFs)
@ -6195,12 +6165,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
break;
case 250: // Mario Block
sec = sides[*lines[i].sidenum].sector - sectors;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
{
P_AddFakeFloor(&sectors[s], &sectors[sec], lines + i,
FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO, secthinkers);
}
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO, secthinkers);
break;
case 251: // A THWOMP!
@ -6247,13 +6212,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
break;
case 258: // Laser block
if (!fromnetsave) // This creates a FOF which disrupts net saves
{
sec = sides[*lines[i].sidenum].sector - sectors;
sec = sides[*lines[i].sidenum].sector - sectors;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
EV_AddLaserThinker(&sectors[s], &sectors[sec], lines + i, secthinkers);
}
// No longer totally disrupts netgames
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
EV_AddLaserThinker(&sectors[s], &sectors[sec], lines + i, secthinkers);
break;
case 259: // Make-Your-Own FOF!
@ -7720,3 +7683,39 @@ static void P_SpawnPushers(void)
break;
}
}
static void P_SearchForDisableLinedefs(void)
{
size_t i;
INT32 j;
// Look for disable linedefs
for (i = 0; i < numlines; i++)
{
if (lines[i].special == 6)
{
// Remove special
// Do *not* remove tag. That would mess with the tag lists
// that P_InitTagLists literally just created!
lines[i].special = 0;
// Ability flags can disable disable linedefs now, lol
if (netgame || multiplayer)
{
// future: nonet flag?
}
else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY)
continue; // Net-only never triggers in single player
else if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
continue;
else if (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
continue;
else if (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX))
continue;
// Disable any linedef specials with our tag.
for (j = -1; (j = P_FindLineFromLineTag(&lines[i], j)) >= 0;)
lines[j].special = 0;
}
}
}

View File

@ -587,7 +587,7 @@ void P_Ticker(boolean run)
}
// Check for pause or menu up in single player
if (paused || P_MenuActivePause())
if (paused || P_AutoPause())
return;
postimgtype = postimgtype2 = postimg_none;

View File

@ -160,15 +160,17 @@ fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move)
return FixedMul(move, FINESINE(angle));
}
boolean P_MenuActivePause(void)
//
// P_AutoPause
// Returns true when gameplay should be halted even if the game isn't necessarily paused.
//
boolean P_AutoPause(void)
{
if (netgame || !menuactive)
// Don't pause even on menu-up or focus-lost in netgames or record attack
if (netgame || modeattacking)
return false;
if (modeattacking)
return false;
return true;
return (menuactive || window_notinfocus);
}
//
@ -328,14 +330,10 @@ void P_GiveEmerald(boolean spawnObj)
//
// P_ResetScore
//
// This is called when your chain is reset. If in
// Chaos mode, it displays what chain you got.
// This is called when your chain is reset.
void P_ResetScore(player_t *player)
{
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS && player->scoreadd >= 5)
CONS_Printf(M_GetText("%s got a chain of %u!\n"), player_names[player-players], player->scoreadd);
#endif
// Formally a host for Chaos mode behavior
player->scoreadd = 0;
}
@ -2540,6 +2538,7 @@ static void P_DoClimbing(player_t *player)
thinker_t *think;
scroll_t *scroller;
angle_t sideangle;
fixed_t dx, dy;
for (think = thinkercap.next; think != &thinkercap; think = think->next)
{
@ -2554,14 +2553,25 @@ static void P_DoClimbing(player_t *player)
if (scroller->affectee != player->lastsidehit)
continue;
if (scroller->accel)
{
dx = scroller->vdx;
dy = scroller->vdy;
}
else
{
dx = scroller->dx;
dy = scroller->dy;
}
if (cmd->forwardmove != 0)
{
player->mo->momz += scroller->dy;
player->mo->momz += dy;
climb = true;
}
else
{
player->mo->momz = scroller->dy;
player->mo->momz = dy;
climb = false;
}
@ -2569,12 +2579,12 @@ static void P_DoClimbing(player_t *player)
if (cmd->sidemove != 0)
{
P_Thrust(player->mo, sideangle, scroller->dx);
P_Thrust(player->mo, sideangle, dx);
climb = true;
}
else
{
P_InstaThrust(player->mo, sideangle, scroller->dx);
P_InstaThrust(player->mo, sideangle, dx);
climb = false;
}
}
@ -2652,6 +2662,125 @@ static void P_DoClimbing(player_t *player)
}
}
//
// PIT_CheckSolidsTeeter
// AKA: PIT_HacksToStopPlayersTeeteringOnGargoyles
//
static mobj_t *teeterer; // the player checking for teetering
static boolean solidteeter; // saves whether the player can teeter on this or not
static fixed_t highesttop; // highest floor found so far
// reserved for standing on multiple objects
static boolean couldteeter;
static fixed_t teeterxl, teeterxh;
static fixed_t teeteryl, teeteryh;
static boolean PIT_CheckSolidsTeeter(mobj_t *thing)
{
fixed_t blockdist;
fixed_t tiptop = FixedMul(MAXSTEPMOVE, teeterer->scale);
fixed_t thingtop = thing->z + thing->height;
fixed_t teeterertop = teeterer->z + teeterer->height;
if (!teeterer || !thing)
return true;
if (!(thing->flags & MF_SOLID))
return true;
if (thing->flags & MF_NOCLIP)
return true;
if (thing == teeterer)
return true;
if (thing->player && cv_tailspickup.value && gametype != GT_HIDEANDSEEK)
return true;
blockdist = teeterer->radius + thing->radius;
if (abs(thing->x - teeterer->x) >= blockdist || abs(thing->y - teeterer->y) >= blockdist)
return true; // didn't hit it
if (teeterer->eflags & MFE_VERTICALFLIP)
{
if (thingtop < teeterer->z)
return true;
if (thing->z > highesttop)
return true;
highesttop = thing->z;
if (thing->z > teeterertop + tiptop)
{
solidteeter = true;
return true;
}
}
else
{
if (thing->z > teeterertop)
return true;
if (thingtop < highesttop)
return true;
highesttop = thingtop;
if (thingtop < teeterer->z - tiptop)
{
solidteeter = true;
return true;
}
}
// are you standing on this?
if ((teeterer->eflags & MFE_VERTICALFLIP && thing->z - FixedMul(FRACUNIT, teeterer->scale) == teeterertop)
|| (!(teeterer->eflags & MFE_VERTICALFLIP) && thingtop + FixedMul(FRACUNIT, teeterer->scale) == teeterer->z))
{
fixed_t teeterdist = thing->radius - FixedMul(5*FRACUNIT, teeterer->scale);
// how far are you from the edge?
if (abs(teeterer->x - thing->x) > teeterdist || abs(teeterer->y - thing->y) > teeterdist)
{
if (couldteeter) // player is standing on another object already, see if we can stand on both and not teeter!
{
if (thing->x - teeterdist < teeterxl)
teeterxl = thing->x - teeterdist;
if (thing->x + teeterdist > teeterxh)
teeterxh = thing->x + teeterdist;
if (thing->y - teeterdist < teeteryl)
teeteryl = thing->y - teeterdist;
if (thing->y + teeterdist > teeteryh)
teeteryh = thing->y + teeterdist;
if (teeterer->x < teeterxl)
return true;
if (teeterer->x > teeterxh)
return true;
if (teeterer->y < teeteryl)
return true;
if (teeterer->y > teeteryh)
return true;
solidteeter = false; // you can stop teetering now!
couldteeter = false; // just in case...
return false;
}
else
{
// too far! don't change teeter status though
// save teeter x/y limits to bring up later
teeterxl = thing->x - teeterdist;
teeterxh = thing->x + teeterdist;
teeteryl = thing->y - teeterdist;
teeteryh = thing->y + teeterdist;
}
couldteeter = true;
return true;
}
solidteeter = false;
couldteeter = false;
return false; // you're definitely not teetering, that's the end of the matter
}
solidteeter = false;
return true; // you're not teetering but it's not neccessarily over, YET
}
//
// P_DoTeeter
//
@ -2826,18 +2955,18 @@ static void P_DoTeeter(player_t *player)
}
}
#ifdef POLYOBJECTS
// Polyobjects
{
INT32 bx, by, xl, xh, yl, yh;
validcount++;
yh = (unsigned)(player->mo->y + player->mo->radius - bmaporgy)>>MAPBLOCKSHIFT;
yl = (unsigned)(player->mo->y - player->mo->radius - bmaporgy)>>MAPBLOCKSHIFT;
xh = (unsigned)(player->mo->x + player->mo->radius - bmaporgx)>>MAPBLOCKSHIFT;
xl = (unsigned)(player->mo->x - player->mo->radius - bmaporgx)>>MAPBLOCKSHIFT;
// Polyobjects
#ifdef POLYOBJECTS
validcount++;
for (by = yl; by <= yh; by++)
for (bx = xl; bx <= xh; bx++)
{
@ -2898,16 +3027,12 @@ static void P_DoTeeter(player_t *player)
}
if (polybottom > player->mo->z + player->mo->height + tiptop
|| (polybottom < player->mo->z
&& player->mo->z + player->mo->height < player->mo->ceilingz - tiptop))
{
|| (polybottom < player->mo->z
&& player->mo->z + player->mo->height < player->mo->ceilingz - tiptop))
teeter = true;
roverfloor = true;
}
else
{
teeter = false;
roverfloor = true;
break;
}
}
@ -2920,16 +3045,12 @@ static void P_DoTeeter(player_t *player)
}
if (polytop < player->mo->z - tiptop
|| (polytop > player->mo->z + player->mo->height
&& player->mo->z > player->mo->floorz + tiptop))
{
|| (polytop > player->mo->z + player->mo->height
&& player->mo->z > player->mo->floorz + tiptop))
teeter = true;
roverfloor = true;
}
else
{
teeter = false;
roverfloor = true;
break;
}
}
@ -2937,8 +3058,27 @@ static void P_DoTeeter(player_t *player)
plink = (polymaplink_t *)(plink->link.next);
}
}
}
#endif
if (teeter) // only bother with objects as a last resort if you were already teetering
{
mobj_t *oldtmthing = tmthing;
tmthing = teeterer = player->mo;
teeterxl = teeterxh = player->mo->x;
teeteryl = teeteryh = player->mo->y;
couldteeter = false;
solidteeter = teeter;
for (by = yl; by <= yh; by++)
for (bx = xl; bx <= xh; bx++)
{
highesttop = INT32_MIN;
if (!P_BlockThingsIterator(bx, by, PIT_CheckSolidsTeeter))
goto teeterdone; // we've found something that stops us teetering at all, how about we stop already
}
teeterdone:
teeter = solidteeter;
tmthing = oldtmthing; // restore old tmthing, goodness knows what the game does with this before mobj thinkers
}
}
if (teeter)
{
if ((player->mo->state == &states[S_PLAY_STND] || player->mo->state == &states[S_PLAY_TAP1] || player->mo->state == &states[S_PLAY_TAP2] || player->mo->state == &states[S_PLAY_SUPERSTAND]))

View File

@ -572,8 +572,8 @@ static boolean R_CheckBBox(fixed_t *bspcoord)
py2 = bspcoord[checkcoord[boxpos][3]];
// check clip list for an open space
angle1 = R_PointToAngle(px1, py1) - viewangle;
angle2 = R_PointToAngle(px2, py2) - viewangle;
angle1 = R_PointToAngle2(viewx>>1, viewy>>1, px1>>1, py1>>1) - viewangle;
angle2 = R_PointToAngle2(viewx>>1, viewy>>1, px2>>1, py2>>1) - viewangle;
span = angle1 - angle2;
@ -702,21 +702,62 @@ static int R_PolysegCompare(const void *p1, const void *p2)
{
const seg_t *seg1 = *(const seg_t * const *)p1;
const seg_t *seg2 = *(const seg_t * const *)p2;
fixed_t dist1, dist2;
fixed_t dist1v1, dist1v2, dist2v1, dist2v2;
// TODO might be a better way to get distance?
#define vxdist(v) FixedMul(R_PointToDist(v->x, v->y), FINECOSINE((R_PointToAngle(v->x, v->y)-viewangle)>>ANGLETOFINESHIFT))+0xFFFFFFF
#define pdist(x, y) (FixedMul(R_PointToDist(x, y), FINECOSINE((R_PointToAngle(x, y)-viewangle)>>ANGLETOFINESHIFT))+0xFFFFFFF)
#define vxdist(v) pdist(v->x, v->y)
dist1 = min(vxdist(seg1->v1), vxdist(seg1->v2));
dist2 = min(vxdist(seg2->v1), vxdist(seg2->v2));
dist1v1 = vxdist(seg1->v1);
dist1v2 = vxdist(seg1->v2);
dist2v1 = vxdist(seg2->v1);
dist2v2 = vxdist(seg2->v2);
if (dist1 == dist2) { // Segs connect toward the front, so use the back verts to determine order!
dist1 = max(vxdist(seg1->v1), vxdist(seg1->v2));
dist2 = max(vxdist(seg2->v1), vxdist(seg2->v2));
if (min(dist1v1, dist1v2) != min(dist2v1, dist2v2))
return min(dist1v1, dist1v2) - min(dist2v1, dist2v2);
{ // That didn't work, so now let's try this.......
fixed_t delta1, delta2, x1, y1, x2, y2;
vertex_t *near1, *near2, *far1, *far2; // wherever you are~
delta1 = R_PointToDist2(seg1->v1->x, seg1->v1->y, seg1->v2->x, seg1->v2->y);
delta2 = R_PointToDist2(seg2->v1->x, seg2->v1->y, seg2->v2->x, seg2->v2->y);
delta1 = FixedDiv(128<<FRACBITS, delta1);
delta2 = FixedDiv(128<<FRACBITS, delta2);
if (dist1v1 < dist1v2)
{
near1 = seg1->v1;
far1 = seg1->v2;
}
else
{
near1 = seg1->v2;
far1 = seg1->v1;
}
if (dist2v1 < dist2v2)
{
near2 = seg2->v1;
far2 = seg2->v2;
}
else
{
near2 = seg2->v2;
far2 = seg2->v1;
}
x1 = near1->x + FixedMul(far1->x-near1->x, delta1);
y1 = near1->y + FixedMul(far1->y-near1->y, delta1);
x2 = near2->x + FixedMul(far2->x-near2->x, delta2);
y2 = near2->y + FixedMul(far2->y-near2->y, delta2);
return pdist(x1, y1)-pdist(x2, y2);
}
#undef vxdist
return dist1-dist2;
#undef pdist
}
//
@ -835,6 +876,7 @@ static void R_Subsector(size_t num)
numffloors = 0;
ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
if (frontsector->ffloors)
{
ffloor_t *rover;
@ -854,6 +896,7 @@ static void R_Subsector(size_t num)
}
ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
if (*rover->bottomheight <= frontsector->ceilingheight
&& *rover->bottomheight >= frontsector->floorheight
&& ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES))
@ -872,6 +915,7 @@ static void R_Subsector(size_t num)
if (numffloors >= MAXFFLOORS)
break;
ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
if (*rover->topheight >= frontsector->floorheight
&& *rover->topheight <= frontsector->ceilingheight
&& ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES))

View File

@ -946,10 +946,12 @@ static void R_InitExtraColormaps(void)
CONS_Printf(M_GetText("Number of Extra Colormaps: %s\n"), sizeu1(numcolormaplumps));
}
// 12/14/14 -- only take flats in F_START/F_END
lumpnum_t R_GetFlatNumForName(const char *name)
{
lumpnum_t lump = W_CheckNumForName(name);
lumpnum_t lump = W_CheckNumForNameInBlock(name, "F_START", "F_END");
if (lump == LUMPERROR)
lump = W_CheckNumForNameInBlock(name, "FF_START", "FF_END"); // deutex, some other old things
if (lump == LUMPERROR)
{
if (strcmp(name, SKYFLATNAME))

View File

@ -162,6 +162,7 @@ consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NU
consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_translucenthud = {"translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_translucency = {"translucency", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -1406,6 +1407,7 @@ void R_RegisterEngineStuff(void)
return;
CV_RegisterVar(&cv_precipdensity);
CV_RegisterVar(&cv_translucency);
CV_RegisterVar(&cv_drawdist);
CV_RegisterVar(&cv_drawdist_nights);
CV_RegisterVar(&cv_drawdist_precip);

View File

@ -88,6 +88,7 @@ extern consvar_t cv_homremoval;
extern consvar_t cv_chasecam, cv_chasecam2;
extern consvar_t cv_flipcam, cv_flipcam2;
extern consvar_t cv_shadow, cv_shadowoffs;
extern consvar_t cv_translucency;
extern consvar_t cv_precipdensity, cv_drawdist, cv_drawdist_nights, cv_drawdist_precip;
extern consvar_t cv_skybox;
extern consvar_t cv_tailspickup;

View File

@ -528,7 +528,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
else
xwalllights = scalelight[rlight->lightnum];
pindex = spryscale>>LIGHTSCALESHIFT;
pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1;
@ -573,7 +573,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
}
// calculate lighting
pindex = spryscale>>LIGHTSCALESHIFT;
pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1;
@ -1130,8 +1130,8 @@ static void R_RenderSegLoop (void)
for (i = 0; i < numffloors; i++)
{
#ifdef POLYOBJECTS_PLANES
//if (curline->polyseg && (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg))
//continue; // Causes issues with FOF planes in The Wall -Red
if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg))
continue;
// FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red
if (curline->polyseg) {
@ -1203,7 +1203,7 @@ static void R_RenderSegLoop (void)
if (segtextured)
{
// calculate lighting
pindex = rw_scale>>LIGHTSCALESHIFT;
pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE-1;
@ -1238,7 +1238,7 @@ static void R_RenderSegLoop (void)
else
xwalllights = scalelight[lightnum];
pindex = rw_scale>>LIGHTSCALESHIFT;
pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE-1;
@ -1359,9 +1359,9 @@ static void R_RenderSegLoop (void)
for (i = 0; i < numffloors; i++)
{
#if 0 //#ifdef POLYOBJECTS_PLANES
if (curline->polyseg && (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg))
continue; // Causes issues with FOF planes in The Wall -Red
#ifdef POLYOBJECTS_PLANES
if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg))
continue;
#endif
ffloor[i].f_frac += ffloor[i].f_step;
@ -1371,9 +1371,9 @@ static void R_RenderSegLoop (void)
{
INT32 y_w;
#if 0 //#ifdef POLYOBJECTS_PLANES
if (curline->polyseg && (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg))
continue; // Causes issues with FOF planes in The Wall -Red
#ifdef POLYOBJECTS_PLANES
if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg))
continue;
#endif
y_w = ffloor[i].b_frac >> HEIGHTBITS;
@ -1520,9 +1520,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (i = 0; i < numffloors; i++)
{
#if 0 //#ifdef POLYOBJECTS_PLANES
if (ds_p->curline->polyseg && (!ffloor[i].polyobj || ffloor[i].polyobj != ds_p->curline->polyseg))
continue; // Causes issues with FOF planes in The Wall -Red
#ifdef POLYOBJECTS_PLANES
if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg))
continue;
#endif
ffloor[i].f_pos = ffloor[i].height - viewz;
}
@ -2021,9 +2021,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (i = 0; i < numffloors; i++)
{
#if 0 //#ifdef POLYOBJECTS_PLANES
if (curline->polyseg && (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg))
continue; // Causes issues with FOF planes in The Wall -Red
#ifdef POLYOBJECTS_PLANES
if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg))
continue;
#endif
ffloor[i].f_pos >>= 4;
@ -2126,7 +2126,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
#ifdef POLYOBJECTS_PLANES
if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES))
{
if (i < MAXFFLOORS && backsector->floorheight <= frontsector->ceilingheight &&
while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++;
if (i < numffloors && backsector->floorheight <= frontsector->ceilingheight &&
backsector->floorheight >= frontsector->floorheight &&
(viewz < backsector->floorheight))
{
@ -2142,7 +2143,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
i++;
}
if (i < MAXFFLOORS && backsector->ceilingheight >= frontsector->floorheight &&
if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight &&
backsector->ceilingheight <= frontsector->ceilingheight &&
(viewz > backsector->ceilingheight))
{

View File

@ -1293,7 +1293,9 @@ static void R_ProjectSprite(mobj_t *thing)
vis->transmap = NULL;
// specific translucency
if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility)
if (!cv_translucency.value)
; // no translucency
else if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility)
vis->transmap = ((tr_trans80-1)<<FF_TRANSSHIFT) + transtables; // because now the translucency is set through FF_TRANSMASK
else if (thing->frame & FF_TRANSMASK)
vis->transmap = (thing->frame & FF_TRANSMASK) - 0x10000 + transtables;

View File

@ -195,15 +195,15 @@ int main(int argc, char **argv)
#ifdef LOGMESSAGES
#if defined(_WIN32_WCE) || defined(GP2X)
logstream = fopen(va("%s.log",argv[0]), "a");
logstream = fopen(va("%s.log",argv[0]), "wt");
#elif defined (_WII)
logstream = fopen(va("%s/srb2log.txt",logdir), "a");
logstream = fopen(va("%s/log.txt",logdir), "wt");
#elif defined (DEFAULTDIR)
if (logdir)
logstream = fopen(va("%s/"DEFAULTDIR"/srb2log.txt",logdir), "a");
logstream = fopen(va("%s/"DEFAULTDIR"/log.txt",logdir), "wt");
else
#endif
logstream = fopen("./srb2log.txt", "a");
logstream = fopen("./log.txt", "wt");
#endif
//I_OutputMsg("I_StartupSystem() ...\n");
@ -228,9 +228,9 @@ int main(int argc, char **argv)
#endif
#endif
// startup SRB2
CONS_Printf("%s", M_GetText("Setting up SRB2...\n"));
CONS_Printf("Setting up SRB2...\n");
D_SRB2Main();
CONS_Printf("%s", M_GetText("Entering main game loop...\n"));
CONS_Printf("Entering main game loop...\n");
// never return
D_SRB2Loop();

View File

@ -301,6 +301,7 @@ SDL_bool framebuffer = SDL_FALSE;
UINT8 keyboard_started = false;
#if !defined (DC)
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
{
//static char msg[] = "oh no! back to reality!\r\n";
@ -318,7 +319,7 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
sigmsg = "SIGILL - illegal instruction - invalid function image";
break;
case SIGFPE:
sigmsg = "SIGFPE - floating point exception";
sigmsg = "SIGFPE - mathematical exception";
break;
case SIGSEGV:
sigmsg = "SIGSEGV - segment violation";
@ -339,7 +340,7 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
sigmsg = sigdef;
}
I_OutputMsg("signal_handler() error: %s\n", sigmsg);
I_OutputMsg("\nsignal_handler() error: %s\n", sigmsg);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
"Signal caught",
@ -350,7 +351,6 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
I_Quit();
}
#if !defined (DC)
FUNCNORETURN static ATTRNORETURN void quit_handler(int num)
{
signal(num, SIG_DFL); //default signal action
@ -743,24 +743,15 @@ static inline void I_ShutdownConsole(void){}
void I_StartupKeyboard (void)
{
#if !defined (DC)
#ifdef SIGILL
signal(SIGILL , signal_handler);
#endif
#ifdef SIGINT
// If these defines don't exist,
// then compilation would have failed above us...
signal(SIGINT , quit_handler);
#endif
#ifdef SIGSEGV
signal(SIGSEGV , signal_handler);
#endif
#ifdef SIGBREAK
signal(SIGBREAK , quit_handler);
#endif
#ifdef SIGABRT
signal(SIGABRT , signal_handler);
#endif
#ifdef SIGTERM
signal(SIGTERM , quit_handler);
#endif
signal(SIGILL , signal_handler);
signal(SIGSEGV , signal_handler);
signal(SIGABRT , signal_handler);
signal(SIGFPE , signal_handler);
#endif
}
@ -2375,62 +2366,38 @@ void I_Error(const char *error, ...)
}
if (errorcount > 20)
{
#ifdef MAC_ALERT
va_start(argptr, error);
vsprintf(buffer, error, argptr);
va_end(argptr);
// 2004-03-03 AJR Since the Mac user is most likely double clicking to run the game, give them a panel.
MacShowAlert("Recursive Error", buffer, "Quit", NULL, NULL);
#elif (defined (_WIN32) || (defined (_WIN32_WCE)) && !defined (__GNUC__)) && !defined (_XBOX)
va_start(argptr,error);
vsprintf(buffer, error, argptr);
va_end(argptr);
#ifndef _WIN32_WCE
{
HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD bytesWritten;
if (co != INVALID_HANDLE_VALUE)
{
if (GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &bytesWritten))
WriteConsoleA(co, buffer, (DWORD)strlen(buffer), NULL, NULL);
else
WriteFile(co, buffer, (DWORD)strlen(buffer), &bytesWritten, NULL);
}
}
#endif
OutputDebugStringA(buffer);
MessageBoxA(vid.WndParent, buffer, "SRB2 Recursive Error", MB_OK|MB_ICONERROR);
#else
// Don't print garbage
va_start(argptr, error);
if (!framebuffer)
vfprintf (stderr, error, argptr);
va_end(argptr);
#endif
// Implement message box with SDL_ShowSimpleMessageBox,
// which should fail gracefully if it can't put a message box up
// on the target system
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
"SRB2 "VERSIONSTRING" Recursive Error",
buffer, NULL);
W_Shutdown();
#ifdef GP2X
chdir("/usr/gp2x");
execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL);
#endif
exit(-1); // recursive errors detected
}
}
shutdowning = true;
I_ShutdownConsole();
#ifndef MAC_ALERT
// Message first.
va_start(argptr,error);
if (!framebuffer)
{
fprintf(stderr, "Error: ");
vfprintf(stderr,error,argptr);
fprintf(stderr, "\n");
}
va_end(argptr);
if (!framebuffer)
fflush(stderr);
#endif
shutdowning = true;
// Display error message in the console before we start shutting it down
va_start(argptr, error);
vsprintf(buffer, error, argptr);
va_end(argptr);
I_OutputMsg("\nI_Error(): %s\n", buffer);
// ---
I_ShutdownConsole();
M_SaveConfig(NULL); // save game config, cvars..
#ifndef NONET
D_SaveBan(); // save the ban list
@ -2454,21 +2421,30 @@ void I_Error(const char *error, ...)
#ifndef _arch_dreamcast
SDL_Quit();
#endif
#ifdef MAC_ALERT
va_start(argptr, error);
vsprintf(buffer, error, argptr);
va_end(argptr);
// 2004-03-03 AJR Since the Mac user is most likely double clicking to run the game, give them a panel.
MacShowAlert("Critical Error", buffer, "Quit", NULL, NULL);
#endif
// Implement message box with SDL_ShowSimpleMessageBox,
// which should fail gracefully if it can't put a message box up
// on the target system
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
"SRB2 "VERSIONSTRING" Error",
buffer, NULL);
// Note that SDL_ShowSimpleMessageBox does *not* require SDL to be
// initialized at the time, so calling it after SDL_Quit() is
// perfectly okay! In addition, we do this on purpose so the
// fullscreen window is closed before displaying the error message
// in case the fullscreen window blocks it for some absurd reason.
W_Shutdown();
#if defined (PARANOIA) && defined (__CYGWIN__)
*(INT32 *)2 = 4; //Alam: Debug!
*(INT32 *)2 = 4; //Alam: Debug!
#endif
#ifdef GP2X
chdir("/usr/gp2x");
execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL);
#endif
exit(-1);
}
@ -2534,6 +2510,7 @@ void I_ShutdownSystem(void)
#ifdef LOGMESSAGES
if (logstream)
{
I_OutputMsg("I_ShutdownSystem(): end of logstream.\n");
fclose(logstream);
logstream = NULL;
}

View File

@ -667,31 +667,28 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
if (mousefocus && kbfocus)
{
// Tell game we got focus back, resume music if necessary
window_notinfocus = false;
if (!paused)
I_ResumeSong(0); //resume it
if (!firsttimeonmouse)
{
if (cv_usemouse.value) I_StartupMouse();
}
//else firsttimeonmouse = SDL_FALSE;
if (gamestate == GS_LEVEL)
{
if (!paused) I_ResumeSong(0); //resume it
}
}
else if (!mousefocus && !kbfocus)
{
// Tell game we lost focus, pause music
window_notinfocus = true;
I_PauseSong(0);
if (!disable_mouse)
{
SDLforceUngrabMouse();
}
if (!netgame && gamestate == GS_LEVEL && !demoplayback && !demorecording && !modeattacking)
{
paused = true;
}
memset(gamekeydown, 0, NUMKEYS); // TODO this is a scary memset
if (gamestate == GS_LEVEL)
{
I_PauseSong(0);
}
if (MOUSE_MENU)
{
@ -1570,7 +1567,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
#ifdef HWRENDER
if (rendermode == render_opengl)
{
window = SDL_CreateWindow("SRB2", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
realwidth, realheight, flags | SDL_WINDOW_OPENGL);
if (window != NULL)
{
@ -1590,7 +1587,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
#endif
if (rendermode == render_soft)
{
window = SDL_CreateWindow("SRB2", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
realwidth, realheight, flags);
if (window != NULL)
{
@ -1775,7 +1772,7 @@ void I_StartupGraphics(void)
// Create window
//Impl_CreateWindow(USE_FULLSCREEN);
//Impl_SetWindowName("SRB2");
//Impl_SetWindowName("SRB2 "VERSIONSTRING);
VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT));
vid.buffer = NULL; // For software mode
@ -1835,12 +1832,17 @@ void I_ShutdownGraphics(void)
bufSurface = NULL;
}
I_OutputMsg("I_ShutdownGraphics(): ");
// was graphics initialized anyway?
if (!graphics_started)
{
I_OutputMsg("graphics never started\n");
return;
CONS_Printf("I_ShutdownGraphics: ");
}
graphics_started = false;
CONS_Printf("%s", M_GetText("shut down\n"));
I_OutputMsg("shut down\n");
#ifdef HWRENDER
if (GLUhandle)
hwClose(GLUhandle);

View File

@ -1214,7 +1214,7 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.12;
CURRENT_PROJECT_VERSION = 2.1.14;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NORMALSRB2,
@ -1226,7 +1226,7 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.12;
CURRENT_PROJECT_VERSION = 2.1.14;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (

View File

@ -1214,7 +1214,7 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.12;
CURRENT_PROJECT_VERSION = 2.1.14;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NORMALSRB2,
@ -1226,7 +1226,7 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.12;
CURRENT_PROJECT_VERSION = 2.1.14;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (

View File

@ -203,7 +203,7 @@ void ST_doPaletteStuff(void)
{
INT32 palette;
if (paused || P_MenuActivePause())
if (paused || P_AutoPause())
palette = 0;
else if (stplyr && stplyr->flashcount)
palette = stplyr->flashpal;
@ -1576,15 +1576,6 @@ static inline void ST_drawTeamName(void)
V_DrawString(244, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "SPECTATOR");
}
#ifdef CHAOSISNOTDEADYET
static inline void ST_drawChaosHUD(void)
{
char chains[33];
sprintf(chains, "CHAINS: %u", stplyr->scoreadd);
V_DrawString(8, STRINGY(184), V_HUDTRANSHALF, chains);
}
#endif
static void ST_drawSpecialStageHUD(void)
{
if (totalrings > 0)
@ -1667,7 +1658,7 @@ static void ST_doHuntIconsAndSound(void)
interval = newinterval;
}
if (!(P_MenuActivePause() || paused) && interval > 0 && leveltime && leveltime % interval == 0)
if (!(P_AutoPause() || paused) && interval > 0 && leveltime && leveltime % interval == 0)
S_StartSound(NULL, sfx_emfind);
}
@ -1727,7 +1718,7 @@ static void ST_doItemFinderIconsAndSound(void)
}
}
if (!(P_MenuActivePause() || paused) && interval > 0 && leveltime && leveltime % interval == 0)
if (!(P_AutoPause() || paused) && interval > 0 && leveltime && leveltime % interval == 0)
S_StartSound(NULL, sfx_emfind);
}
@ -1814,12 +1805,6 @@ static void ST_overlayDrawer(void)
if (G_GametypeHasTeams())
ST_drawTeamName();
// Chaos HUD Stuff
#ifdef CHAOSISNOTDEADYET
else if (gametype == GT_CHAOS)
ST_drawChaosHUD();
#endif
// Special Stage HUD
if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer])
ST_drawSpecialStageHUD();

View File

@ -662,6 +662,32 @@ lumpnum_t W_GetNumForName(const char *name)
return i;
}
//
// W_CheckNumForNameInBlock
// Checks only in blocks from blockstart lump to blockend lump
//
lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend)
{
INT32 i;
lumpnum_t bsid, beid;
lumpnum_t check = INT16_MAX;
// scan wad files backwards so patch lump files take precedence
for (i = numwadfiles - 1; i >= 0; i--)
{
bsid = W_CheckNumForNamePwad(blockstart,(UINT16)i,0);
if (bsid == INT16_MAX)
continue; // block doesn't exist, keep going
beid = W_CheckNumForNamePwad(blockend,(UINT16)i,0);
// if block end doesn't exist, just search through everything
check = W_CheckNumForNamePwad(name,(UINT16)i,bsid);
if (check < beid)
return (i<<16)+check; // found it, in our constraints
}
return LUMPERROR;
}
// Used by Lua. Case sensitive lump checking, quickly...
#include "fastcmp.h"
UINT8 W_LumpExists(const char *name)

View File

@ -102,6 +102,7 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum);
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad
lumpnum_t W_CheckNumForName(const char *name);
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR
lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend);
UINT8 W_LumpExists(const char *name); // Lua uses this.
size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump);

View File

@ -588,7 +588,7 @@ void Y_Ticker(void)
return;
// Check for pause or menu up in single player
if (paused || P_MenuActivePause())
if (paused || P_AutoPause())
return;
intertic++;
@ -907,11 +907,7 @@ void Y_StartIntermission(void)
intertype = int_teammatch;
else if (gametype == GT_MATCH
|| gametype == GT_TAG
|| gametype == GT_HIDEANDSEEK
#ifdef CHAOSISNOTDEADYET
|| gametype == GT_CHAOS
#endif
)
|| gametype == GT_HIDEANDSEEK)
intertype = int_match;
else if (gametype == GT_RACE)
intertype = int_race;

View File

@ -25,9 +25,6 @@ typedef enum
int_teammatch,// Team Match
// int_tag, // Tag
int_ctf, // CTF
#ifdef CHAOSISNOTDEADYET
int_chaos, // Chaos
#endif
int_spec, // Special Stage
int_nights, // NiGHTS into Dreams
int_nightsspec,// NiGHTS special stage