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 (why do we keep the version number up to date
when everything else in this file is hilariously old? when everything else in this file is hilariously old?
- Inuyasha) - 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! if (!stricmp(name, cmd->name)) //case insensitive now that we have lower and uppercase!
{ {
#ifdef HAVE_BLUA
// don't I_Error for Lua commands // don't I_Error for Lua commands
// Lua commands can replace game commands, and they have priority. // 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, // 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. // it's good to have this here so we find out.
if (cmd->function != COM_Lua_f) if (cmd->function != COM_Lua_f)
#endif
I_Error("Command %s already exists\n", name); I_Error("Command %s already exists\n", name);
return; return;
@ -397,6 +399,7 @@ void COM_AddCommand(const char *name, com_func_t func)
com_commands = cmd; com_commands = cmd;
} }
#ifdef HAVE_BLUA
/** Adds a console command for Lua. /** Adds a console command for Lua.
* No I_Errors allowed; return a negative code instead. * No I_Errors allowed; return a negative code instead.
* *
@ -429,6 +432,7 @@ int COM_AddLuaCommand(const char *name)
com_commands = cmd; com_commands = cmd;
return 0; return 0;
} }
#endif
/** Tests if a command exists. /** Tests if a command exists.
* *
@ -1284,6 +1288,8 @@ void CV_LoadNetVars(UINT8 **p)
serverloading = false; serverloading = false;
} }
static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth);
void CV_ResetCheatNetVars(void) void CV_ResetCheatNetVars(void)
{ {
consvar_t *cvar; consvar_t *cvar;
@ -1291,7 +1297,7 @@ void CV_ResetCheatNetVars(void)
// Stealthset everything back to default. // Stealthset everything back to default.
for (cvar = consvar_vars; cvar; cvar = cvar->next) for (cvar = consvar_vars; cvar; cvar = cvar->next)
if (cvar->flags & CV_CHEAT) 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 // 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; INT32 newvalue, max;
// count pointlimit better // count pointlimit better
if (var == &cv_pointlimit && (gametype == GT_MATCH if (var == &cv_pointlimit && (gametype == GT_MATCH))
#ifdef CHAOSISNOTDEADYET
|| gametype == GT_CHAOS
#endif
))
increment *= 50; increment *= 50;
newvalue = var->value + increment; newvalue = var->value + increment;

View file

@ -823,7 +823,7 @@ static inline void resynch_read_ctf(resynchend_pak *p)
{ {
if (!playeringame[p->flagplayer[1]]) if (!playeringame[p->flagplayer[1]])
I_Error("Invalid blue flag player %d who isn't in the game!", (INT32)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) if (blueflag)
{ {
P_RemoveMobj(blueflag); P_RemoveMobj(blueflag);

View file

@ -90,6 +90,9 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#include "hardware/hw3sound.h" #include "hardware/hw3sound.h"
#endif #endif
// platform independant focus loss
UINT8 window_notinfocus = false;
// //
// DEMO LOOP // DEMO LOOP
// //
@ -437,6 +440,17 @@ static void D_Display(void)
CON_Drawer(); CON_Drawer();
M_Drawer(); // menu is drawn even on top of everything 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 NetUpdate(); // send out any new accumulation
// It's safe to end the game now. // It's safe to end the game now.
@ -635,6 +649,7 @@ void D_AdvanceDemo(void)
// //
void D_StartTitle(void) void D_StartTitle(void)
{ {
INT32 i;
if (netgame) if (netgame)
{ {
if (gametype == GT_COOP) if (gametype == GT_COOP)
@ -661,6 +676,16 @@ void D_StartTitle(void)
SV_StopServer(); SV_StopServer();
SV_ResetServer(); 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, // In case someone exits out at the same time they start a time attack run,
// reset modeattacking // reset modeattacking
modeattacking = ATTACKING_NONE; modeattacking = ATTACKING_NONE;
@ -803,7 +828,7 @@ static void IdentifyVersion(void)
D_AddFile(va(pandf,srb2waddir,"rings.dta")); D_AddFile(va(pandf,srb2waddir,"rings.dta"));
// Add our crappy patches to fix our bugs // 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) #if !defined (HAVE_SDL) || defined (HAVE_MIXER)
{ {
@ -1087,19 +1112,19 @@ void D_SRB2Main(void)
#endif #endif
D_CleanFile(); D_CleanFile();
#if 1 // md5s last updated 11/10/14 #if 1 // md5s last updated 12/14/14
// Check MD5s of autoloaded files // Check MD5s of autoloaded files
W_VerifyFileMD5(0, "ac309fb3c7d4b5b685e2cd26beccf0e8"); // srb2.srb/srb2.wad W_VerifyFileMD5(0, "c1b9577687f8a795104aef4600720ea7"); // srb2.srb/srb2.wad
W_VerifyFileMD5(1, "f39b6c849295e3c81875726e8cc0e2c7"); // zones.dta W_VerifyFileMD5(1, "303838c6c534d9540288360fa49cca60"); // zones.dta
W_VerifyFileMD5(2, "cfca0f1c73023cbbd8f844f45480f799"); // player.dta W_VerifyFileMD5(2, "cfca0f1c73023cbbd8f844f45480f799"); // player.dta
W_VerifyFileMD5(3, "85901ad4bf94637e5753d2ac2c03ea26"); // rings.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 // 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. // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
#endif #endif
mainwads = 5; // there are 5 wads not to unload mainwads = 4; // there are 5 wads not to unload
cht_Init(); 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_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}; 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_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_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}; 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_competitionboxes);
CV_RegisterVar(&cv_matchboxes); 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_recycler);
CV_RegisterVar(&cv_teleporters); CV_RegisterVar(&cv_teleporters);
CV_RegisterVar(&cv_superring); CV_RegisterVar(&cv_superring);
@ -699,6 +672,8 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_invertmouse2); CV_RegisterVar(&cv_invertmouse2);
CV_RegisterVar(&cv_mousesens); CV_RegisterVar(&cv_mousesens);
CV_RegisterVar(&cv_mousesens2); CV_RegisterVar(&cv_mousesens2);
CV_RegisterVar(&cv_mouseysens);
CV_RegisterVar(&cv_mouseysens2);
CV_RegisterVar(&cv_mousemove); CV_RegisterVar(&cv_mousemove);
CV_RegisterVar(&cv_mousemove2); CV_RegisterVar(&cv_mousemove2);
@ -734,9 +709,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_width);
CV_RegisterVar(&cv_scr_height); CV_RegisterVar(&cv_scr_height);
// p_fab.c
CV_RegisterVar(&cv_translucency);
CV_RegisterVar(&cv_soundtest); CV_RegisterVar(&cv_soundtest);
// ingame object placing // ingame object placing
@ -3374,18 +3346,6 @@ void D_GameTypeChanged(INT32 lastgametype)
switch (gametype) 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_MATCH:
case GT_TEAMMATCH: case GT_TEAMMATCH:
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits 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")) 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; return;
} }
if (CV_CheatsEnabled()) if (CV_CheatsEnabled())
{ {
CONS_Printf(M_GetText("At least one CHEAT-marked variable has been changed -- Cheats are enabled.\n")); 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 else
CONS_Printf(M_GetText("No CHEAT-marked variables are changed -- Cheats are disabled.\n")); 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_alwaysfreelook2;
extern consvar_t cv_mousemove2; extern consvar_t cv_mousemove2;
extern consvar_t cv_mousesens2; extern consvar_t cv_mousesens2;
extern consvar_t cv_mouseysens2;
// normally in p_mobj but the .h is not read // normally in p_mobj but the .h is not read
extern consvar_t cv_itemrespawntime; 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_analog, cv_analog2;
extern consvar_t cv_netstat; extern consvar_t cv_netstat;
extern consvar_t cv_translucency;
extern consvar_t cv_splats; extern consvar_t cv_splats;
extern consvar_t cv_countdowntime; 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; 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 #ifdef NEWPING
extern consvar_t cv_maxping; extern consvar_t cv_maxping;
#endif #endif

View file

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

View file

@ -144,8 +144,8 @@ extern FILE *logstream;
#define VERSIONSTRING "Trunk" #define VERSIONSTRING "Trunk"
#else #else
#define VERSION 201 // Game version #define VERSION 201 // Game version
#define SUBVERSION 12 // more precise version number #define SUBVERSION 14 // more precise version number
#define VERSIONSTRING "v2.1.12" #define VERSIONSTRING "v2.1.14"
// Hey! If you change this, add 1 to the MODVERSION below! // Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates! // Otherwise we can't force updates!
#endif #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. // 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. // 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". // 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. /// Dumps the contents of a network save game upon consistency failure for debugging.
//#define DUMPCONSISTENCY //#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 /// Polyobject fake flat code
#define POLYOBJECTS_PLANES #define POLYOBJECTS_PLANES

View file

@ -103,6 +103,7 @@ extern boolean digital_disabled;
extern boolean menuactive; // Menu overlaid? extern boolean menuactive; // Menu overlaid?
extern UINT8 paused; // Game paused? 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 nodrawers;
extern boolean noblit; 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? // why build a ticcmd if we're paused?
// Or, for that matter, if we're being reborn. // 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->angleturn = (INT16)(localangle >> 16);
cmd->aiming = G_ClipAimingPitch(&localaiming); 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? //why build a ticcmd if we're paused?
// Or, for that matter, if we're being reborn. // 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->angleturn = (INT16)(localangle2 >> 16);
cmd->aiming = G_ClipAimingPitch(&localaiming2); cmd->aiming = G_ClipAimingPitch(&localaiming2);
@ -2299,11 +2299,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
// -- DM/Tag/CTF-spectator/etc -- // -- DM/Tag/CTF-spectator/etc --
// Order: DM->CTF->Coop // Order: DM->CTF->Coop
else if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF else if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF
|| ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && !(players[playernum].pflags & PF_TAGIT)) || ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && !(players[playernum].pflags & PF_TAGIT)))
#ifdef CHAOSISNOTDEADYET
|| gametype == GT_CHAOS
#endif
)
{ {
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
&& !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF 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_RACE) return TOL_RACE;
if (pgametype == GT_MATCH) return TOL_MATCH; if (pgametype == GT_MATCH) return TOL_MATCH;
if (pgametype == GT_TEAMMATCH) 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_TAG) return TOL_TAG;
if (pgametype == GT_HIDEANDSEEK) return TOL_TAG; if (pgametype == GT_HIDEANDSEEK) return TOL_TAG;
if (pgametype == GT_CTF) return TOL_CTF; 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 // 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_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_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}; consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
INT32 mousex, mousey; INT32 mousex, mousey;
@ -99,7 +101,7 @@ void G_MapEventsToControls(event_t *ev)
case ev_mouse: // buttons are virtual keys case ev_mouse: // buttons are virtual keys
mousex = (INT32)(ev->data2*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f)); 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)); 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; break;
case ev_joystick: // buttons are virtual keys case ev_joystick: // buttons are virtual keys
@ -121,7 +123,7 @@ void G_MapEventsToControls(event_t *ev)
case ev_mouse2: // buttons are virtual keys case ev_mouse2: // buttons are virtual keys
mouse2x = (INT32)(ev->data2*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f)); 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)); 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; break;
default: default:

View file

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

View file

@ -278,6 +278,7 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[SMALLREDBALL_L], // SPR_TRLS &lspr[SMALLREDBALL_L], // SPR_TRLS
&lspr[NOLIGHT], // SPR_CBLL &lspr[NOLIGHT], // SPR_CBLL
&lspr[NOLIGHT], // SPR_AROW &lspr[NOLIGHT], // SPR_AROW
&lspr[NOLIGHT], // SPR_CFIR
// Greenflower Scenery // Greenflower Scenery
&lspr[NOLIGHT], // SPR_FWR1 &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 // 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; sSurf.FlatColor.s.alpha = 0x20;
else if (spr->mobj->frame & FF_TRANSMASK) else if (spr->mobj->frame & FF_TRANSMASK)
{ {

View file

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

View file

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

View file

@ -57,9 +57,19 @@
#undef DEBUG_TO_FILE // maybe defined in previous *.h #undef DEBUG_TO_FILE // maybe defined in previous *.h
#define DEBUG_TO_FILE // output debugging msgs to ogllog.txt #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 #undef DEBUG_TO_FILE
#endif #endif
//#if defined(HAVE_SDL) && !defined(_DEBUG)
//#undef DEBUG_TO_FILE
//#endif
#ifdef DEBUG_TO_FILE
extern FILE *gllogstream;
#endif
#ifndef DRIVER_STRING #ifndef DRIVER_STRING
// #define USE_PALETTED_TEXTURE // #define USE_PALETTED_TEXTURE
@ -117,9 +127,6 @@ extern PFNglGetString pglGetString;
extern const GLubyte *gl_extensions; extern const GLubyte *gl_extensions;
extern RGBA_t myPaletteData[]; extern RGBA_t myPaletteData[];
#ifndef HAVE_SDL
extern FILE *logstream;
#endif
extern GLint screen_width; extern GLint screen_width;
extern GLint screen_height; extern GLint screen_height;
extern GLbyte screen_depth; 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_TRLS,
SPR_CBLL, // Cannonball SPR_CBLL, // Cannonball
SPR_AROW, // Arrow SPR_AROW, // Arrow
SPR_CFIR, // Colored fire of various sorts
// Greenflower Scenery // Greenflower Scenery
SPR_FWR1, SPR_FWR1,
@ -1907,7 +1908,12 @@ typedef enum state
S_ARROWDOWN, S_ARROWDOWN,
// Trapgoyle Demon fire // Trapgoyle Demon fire
S_DEMONFIRE, S_DEMONFIRE1,
S_DEMONFIRE2,
S_DEMONFIRE3,
S_DEMONFIRE4,
S_DEMONFIRE5,
S_DEMONFIRE6,
S_GFZFLOWERA, S_GFZFLOWERA,
S_GFZFLOWERA2, S_GFZFLOWERA2,
@ -3934,7 +3940,6 @@ typedef enum mobj_type
MT_NIGHTOPIANHELPER, // the actual helper object that orbits you MT_NIGHTOPIANHELPER, // the actual helper object that orbits you
// Utility Objects // Utility Objects
MT_CHAOSSPAWNER,
MT_TELEPORTMAN, MT_TELEPORTMAN,
MT_ALTVIEWMAN, MT_ALTVIEWMAN,
MT_CRUMBLEOBJ, // Sound generator for crumbling platform 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_HIDEANDSEEK, "Hide and Seek"},
{GT_CTF, "CTF"}, {GT_CTF, "CTF"},
#ifdef CHAOSISNOTDEADYET
{GT_CHAOS, "Chaos"},
#endif
{0, NULL} {0, NULL}
}; };
consvar_t cv_newgametype = {"newgametype", "Co-op", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 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, "Mouse Move", &cv_mousemove, 40},
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 50}, {IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 50},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, {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[] = static menuitem_t OP_Mouse2OptionsMenu[] =
@ -1139,9 +1138,11 @@ static menuitem_t OP_Mouse2OptionsMenu[] =
&cv_mouse2port, 20}, &cv_mouse2port, 20},
{IT_STRING | IT_CVAR, NULL, "Always MouseLook", &cv_alwaysfreelook2, 30}, {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, "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, {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[] = 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_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_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)) || ((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_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))) (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)) if (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE))
return true; return true;
#ifdef CHAOSISNOTDEADYET
if (gt == GT_CHAOS && (mapheaderinfo[mapnum]->typeoflevel & TOL_CHAOS))
return true;
#endif
return false; return false;
case LLM_LEVELSELECT: case LLM_LEVELSELECT:

View file

@ -2715,14 +2715,6 @@ void A_BossDeath(mobj_t *mo)
P_LinedefExecute(LE_BOSSDEAD, mo, NULL); P_LinedefExecute(LE_BOSSDEAD, mo, NULL);
mo->health = 0; mo->health = 0;
#ifdef CHAOSISNOTDEADYET
if (mo->flags2 & MF2_CHAOSBOSS)
{
P_RemoveMobj(mo);
return;
}
#endif
// Boss is dead (but not necessarily fleeing...) // Boss is dead (but not necessarily fleeing...)
// Lua may use this to ignore bosses after they start fleeing // Lua may use this to ignore bosses after they start fleeing
mo->flags2 |= MF2_BOSSDEAD; mo->flags2 |= MF2_BOSSDEAD;
@ -5635,10 +5627,11 @@ void A_MixUp(mobj_t *actor)
// //
void A_RecyclePowers(mobj_t *actor) void A_RecyclePowers(mobj_t *actor)
{ {
#ifdef WEIGHTEDRECYCLER
INT32 i, j, k, numplayers = 0; INT32 i, j, k, numplayers = 0;
#ifdef WEIGHTEDRECYCLER
UINT8 beneficiary = 255; UINT8 beneficiary = 255;
#endif
UINT8 playerslist[MAXPLAYERS]; UINT8 playerslist[MAXPLAYERS];
UINT8 postscramble[MAXPLAYERS]; UINT8 postscramble[MAXPLAYERS];
@ -5651,6 +5644,11 @@ void A_RecyclePowers(mobj_t *actor)
return; return;
#endif #endif
#if !defined(WEIGHTEDRECYCLER) && !defined(HAVE_BLUA)
// actor is used in all scenarios but this one, funny enough
(void)actor;
#endif
if (!multiplayer) if (!multiplayer)
return; return;
@ -5665,9 +5663,11 @@ void A_RecyclePowers(mobj_t *actor)
numplayers++; numplayers++;
postscramble[j] = playerslist[j] = (UINT8)i; postscramble[j] = playerslist[j] = (UINT8)i;
#ifdef WEIGHTEDRECYCLER
// The guy who started the recycle gets the best result // The guy who started the recycle gets the best result
if (actor && actor->target && actor->target->player && &players[i] == actor->target->player) if (actor && actor->target && actor->target->player && &players[i] == actor->target->player)
beneficiary = (UINT8)i; beneficiary = (UINT8)i;
#endif
// Save powers // Save powers
for (k = 0; k < NUMPOWERS; k++) for (k = 0; k < NUMPOWERS; k++)
@ -5684,6 +5684,13 @@ void A_RecyclePowers(mobj_t *actor)
return; //nobody to touch! return; //nobody to touch!
//shuffle the post scramble list, whee! //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++) for (j = 0; j < numplayers; j++)
{ {
UINT8 tempint; UINT8 tempint;
@ -5694,6 +5701,7 @@ void A_RecyclePowers(mobj_t *actor)
postscramble[i] = tempint; postscramble[i] = tempint;
} }
#ifdef WEIGHTEDRECYCLER
//the joys of qsort... //the joys of qsort...
if (beneficiary != 255) { if (beneficiary != 255) {
qsort(playerslist, numplayers, sizeof(UINT8), P_RecycleCompare); qsort(playerslist, numplayers, sizeof(UINT8), P_RecycleCompare);
@ -5710,6 +5718,7 @@ void A_RecyclePowers(mobj_t *actor)
} }
} }
} }
#endif
// now assign! // now assign!
for (i = 0; i < numplayers; i++) for (i = 0; i < numplayers; i++)
@ -5737,137 +5746,6 @@ void A_RecyclePowers(mobj_t *actor)
P_RestoreMusic(&players[recv_pl]); P_RestoreMusic(&players[recv_pl]);
P_FlashPal(&players[recv_pl], PAL_RECYCLE, 10); 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 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->momy = FixedMul(FINESINE(fa),ns);
goop->momz = FixedMul(4*FRACUNIT, actor->scale); goop->momz = FixedMul(4*FRACUNIT, actor->scale);
goop->fuse = 10*TICRATE;
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS)
goop->fuse = 5*TICRATE;
else
#endif
goop->fuse = 10*TICRATE;
} }
actor->reactiontime = 0; // we already shot goop, so don't do it again! actor->reactiontime = 0; // we already shot goop, so don't do it again!
if (actor->info->attacksound) if (actor->info->attacksound)

View file

@ -11,124 +11,5 @@
/// \brief some new action routines, separated from the original doom /// \brief some new action routines, separated from the original doom
/// sources, so that you can include it or remove it easy. /// sources, so that you can include it or remove it easy.
#include "doomdef.h" /// \todo
#include "g_game.h" /// This file is now unused, please remove at some point
#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;
}

View file

@ -1590,33 +1590,6 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
case MT_SPIKE: case MT_SPIKE:
str = M_GetText("%s was %s by spikes.\n"); str = M_GetText("%s was %s by spikes.\n");
break; 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: default:
str = M_GetText("%s was %s by an environmental hazard.\n"); str = M_GetText("%s was %s by an environmental hazard.\n");
break; 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! if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording!
G_StopMetalRecording(); 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 if (gametype == GT_MATCH && cv_match_scoring.value == 0 // note, no team match suicide penalty
&& ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player))) && ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player)))
{ // Suicide penalty { // Suicide penalty
@ -1896,39 +1864,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{ {
INT32 score = 0; 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 (maptol & TOL_NIGHTS) // Enemies always worth 200, bosses don't do anything.
{ {
if ((target->flags & MF_ENEMY) && !(target->flags & (MF_MISSILE|MF_BOSS))) 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 // This determines the kind of object spawned
// during the death frame of a thing. // during the death frame of a thing.
if (!mariomode // Don't show birds, etc. in Mario Mode Tails 12-23-2001 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) && target->flags & MF_ENEMY)
{ {
if (cv_soniccd.value) if (cv_soniccd.value)
@ -2512,11 +2444,7 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
return false; return false;
// In COOP/RACE/CHAOS, you can't hurt other players unless cv_friendlyfire is on // In COOP/RACE/CHAOS, you can't hurt other players unless cv_friendlyfire is on
if (!cv_friendlyfire.value && (G_PlatformGametype() if (!cv_friendlyfire.value && (G_PlatformGametype()))
#ifdef CHAOSISNOTDEADYET
|| gametype == GT_CHAOS
#endif
))
return false; return false;
// Tag handling // Tag handling
@ -2843,17 +2771,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (target->health > 1) 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) if (target->info->painsound)
S_StartSound(target, 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) if (target->health > 1)
target->flags2 |= MF2_FRET; 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 #ifdef HAVE_BLUA
else if (target->flags & MF_ENEMY) else if (target->flags & MF_ENEMY)

View file

@ -144,7 +144,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives);
UINT8 P_GetNextEmerald(void); UINT8 P_GetNextEmerald(void);
void P_GiveEmerald(boolean spawnObj); void P_GiveEmerald(boolean spawnObj);
void P_ResetScore(player_t *player); void P_ResetScore(player_t *player);
boolean P_MenuActivePause(void); boolean P_AutoPause(void);
void P_DoJumpShield(player_t *player); void P_DoJumpShield(player_t *player);
void P_BlackOw(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_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) static void P_RingZMovement(mobj_t *mo)
{ {
I_Assert(mo != NULL); I_Assert(mo != NULL);
@ -1361,43 +1488,9 @@ static void P_RingZMovement(mobj_t *mo)
// Intercept the stupid 'fall through 3dfloors' bug // Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors) if (mo->subsector->sector->ffloors)
{ P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 1);
ffloor_t *rover; if (mo->subsector->polyList)
fixed_t delta1, delta2; P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
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;
}
}
}
// adjust height // adjust height
if (mo->pmomz && mo->z != mo->floorz) 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(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo)); 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_BLOCKMONSTERS)
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > *rover->topheight - FixedMul(16*FRACUNIT, mo->scale))) && ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > *rover->topheight - FixedMul(16*FRACUNIT, mo->scale)))
return true; return true;
@ -1464,55 +1557,9 @@ static boolean P_ZMovement(mobj_t *mo)
// Intercept the stupid 'fall through 3dfloors' bug // Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors) if (mo->subsector->sector->ffloors)
{ P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
ffloor_t *rover; if (mo->subsector->polyList)
fixed_t delta1, delta2, thingtop = mo->z + mo->height; P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
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;
}
}
}
// adjust height // adjust height
if (mo->pmomz && mo->z != mo->floorz) 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 // Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors) if (mo->subsector->sector->ffloors)
{ P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
ffloor_t *rover; if (mo->subsector->polyList)
fixed_t delta1, delta2; P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
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;
}
}
}
// check for smooth step up // check for smooth step up
if ((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height > mo->ceilingz) if ((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height > mo->ceilingz)
@ -2052,26 +2063,24 @@ static void P_PlayerZMovement(mobj_t *mo)
while(po) while(po)
{ {
if (!P_MobjInsidePolyobj(po, mo)) if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID))
{
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))
{ {
po = (polyobj_t *)(po->link.next); po = (polyobj_t *)(po->link.next);
continue; continue;
} }
// We're inside it! Yess... // 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) if (mo->z == polysec->ceilingheight)
{ {
@ -2241,42 +2250,9 @@ static boolean P_SceneryZMovement(mobj_t *mo)
{ {
// Intercept the stupid 'fall through 3dfloors' bug // Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors) if (mo->subsector->sector->ffloors)
{ P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 2);
ffloor_t *rover; if (mo->subsector->polyList)
fixed_t delta1, delta2; P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
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;
}
}
}
// adjust height // adjust height
if (mo->pmomz && mo->z != mo->floorz) if (mo->pmomz && mo->z != mo->floorz)
@ -3371,11 +3347,7 @@ static void P_Boss2Thinker(mobj_t *mobj)
if (!mobj->movecount) if (!mobj->movecount)
mobj->flags2 &= ~MF2_FRET; mobj->flags2 &= ~MF2_FRET;
if (!mobj->tracer if (!mobj->tracer)
#ifdef CHAOSISNOTDEADYET
&& gametype != GT_CHAOS
#endif
)
{ {
var1 = 0; var1 = 0;
A_BossJetFume(mobj); A_BossJetFume(mobj);
@ -3398,11 +3370,7 @@ static void P_Boss2Thinker(mobj_t *mobj)
return; return;
} }
if (mobj->state == &states[mobj->info->spawnstate] && mobj->health > mobj->info->damage if (mobj->state == &states[mobj->info->spawnstate] && mobj->health > mobj->info->damage)
#ifdef CHAOSISNOTDEADYET
&& gametype != GT_CHAOS
#endif
)
A_Boss2Chase(mobj); A_Boss2Chase(mobj);
else if (mobj->health > 0 && mobj->state != &states[mobj->info->painstate] && mobj->state != &states[mobjinfo[mobj->info->missilestate].raisestate]) 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 void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on your target
{ {
fixed_t dist, ndist, speedmul; fixed_t dist, ndist, speedmul;
@ -6130,14 +6072,6 @@ void P_MobjThinker(mobj_t *mobj)
return; 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)); 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)); 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; 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)); 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)); 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; return;
} }
#ifdef CHAOSISNOTDEADYET
if (gametype == GT_CHAOS && mobj->target->health <= 0)
{
P_RemoveMobj(mobj);
return;
}
#endif
P_UnsetThingPosition(mobj); P_UnsetThingPosition(mobj);
mobj->x = mobj->target->x; mobj->x = mobj->target->x;
mobj->y = mobj->target->y; 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 P_RemoveMobj(mobj); // make sure they disappear
return; 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: case MT_METALSONIC_BATTLE:
break; // don't remove break; // don't remove
case MT_SPIKE: case MT_SPIKE:
@ -8178,7 +7955,8 @@ void P_SpawnMapThing(mapthing_t *mthing)
if (i == NUMMOBJTYPES) 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; return;
CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y);
i = MT_UNKNOWN; i = MT_UNKNOWN;
@ -8597,15 +8375,6 @@ ML_NOCLIMB : Direction not controllable
if (mthing->angle > 0) if (mthing->angle > 0)
mobj->health = mthing->angle; mobj->health = mthing->angle;
break; 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_TRAPGOYLE:
case MT_TRAPGOYLEUP: case MT_TRAPGOYLEUP:
case MT_TRAPGOYLEDOWN: case MT_TRAPGOYLEDOWN:

View file

@ -43,6 +43,16 @@
#define FF_TRANSMASK 0xf0000 #define FF_TRANSMASK 0xf0000
/// \brief shift for FF_TRANSMASK /// \brief shift for FF_TRANSMASK
#define FF_TRANSSHIFT 16 #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 /** \brief translucency tables

View file

@ -990,6 +990,241 @@ static inline UINT32 SavePlayer(const player_t *player)
return 0xFFFFFFFF; 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 // SaveSpecialLevelThinker
// //
@ -1395,9 +1630,6 @@ static inline void SaveWhatThinker(const thinker_t *th, const UINT8 type)
static void P_NetArchiveThinkers(void) static void P_NetArchiveThinkers(void)
{ {
const thinker_t *th; const thinker_t *th;
const mobj_t *mobj;
UINT32 diff;
UINT16 diff2;
WRITEUINT32(save_p, ARCHIVEBLOCK_THINKERS); WRITEUINT32(save_p, ARCHIVEBLOCK_THINKERS);
@ -1406,230 +1638,8 @@ static void P_NetArchiveThinkers(void)
{ {
if (th->function.acp1 == (actionf_p1)P_MobjThinker) if (th->function.acp1 == (actionf_p1)P_MobjThinker)
{ {
mobj = (const mobj_t *)th; SaveMobjThinker(th, tc_mobj);
continue;
// 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);
} }
#ifdef PARANOIA #ifdef PARANOIA
else if (th->function.acp1 == (actionf_p1)P_RainThinker else if (th->function.acp1 == (actionf_p1)P_RainThinker
@ -1862,6 +1872,232 @@ static inline player_t *LoadPlayer(UINT32 player)
return &players[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 // LoadSpecialLevelThinker
// //
@ -2131,11 +2367,15 @@ static void LoadPusherThinker(actionf_p1 thinker)
static inline void LoadLaserThinker(actionf_p1 thinker) static inline void LoadLaserThinker(actionf_p1 thinker)
{ {
laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ffloor_t *rover = NULL;
ht->thinker.function.acp1 = thinker; ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p)); ht->sector = LoadSector(READUINT32(save_p));
ht->ffloor = NULL;
ht->sec = LoadSector(READUINT32(save_p)); ht->sec = LoadSector(READUINT32(save_p));
ht->sourceline = LoadLine(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); P_AddThinker(&ht->thinker);
} }
@ -2333,13 +2573,8 @@ static void P_NetUnArchiveThinkers(void)
{ {
thinker_t *currentthinker; thinker_t *currentthinker;
thinker_t *next; thinker_t *next;
mobj_t *mobj;
UINT32 diff;
UINT16 diff2;
INT32 i;
UINT8 tclass; UINT8 tclass;
UINT8 restoreNum = false; UINT8 restoreNum = false;
fixed_t z, floorz, ceilingz;
if (READUINT32(save_p) != ARCHIVEBLOCK_THINKERS) if (READUINT32(save_p) != ARCHIVEBLOCK_THINKERS)
I_Error("Bad $$$.sav at archive block Thinkers"); I_Error("Bad $$$.sav at archive block Thinkers");
@ -2350,7 +2585,6 @@ static void P_NetUnArchiveThinkers(void)
{ {
next = currentthinker->next; next = currentthinker->next;
mobj = (mobj_t *)currentthinker;
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
P_RemoveSavegameMobj((mobj_t *)currentthinker); // item isn't saved, don't remove it P_RemoveSavegameMobj((mobj_t *)currentthinker); // item isn't saved, don't remove it
else else
@ -2372,216 +2606,7 @@ static void P_NetUnArchiveThinkers(void)
switch (tclass) switch (tclass)
{ {
case tc_mobj: case tc_mobj:
diff = READUINT32(save_p); LoadMobjThinker((actionf_p1)P_MobjThinker);
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
break; break;
case tc_ceiling: 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) 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 bbox[4];
fixed_t by2 = by1 + MAPBLOCKUNITS; line_t testline;
line_t boxline, testline; vertex_t vtest;
vertex_t vbox, vtest;
bbox[BOXRIGHT] = bx1 + MAPBLOCKUNITS;
bbox[BOXTOP] = by1 + MAPBLOCKUNITS;
bbox[BOXLEFT] = bx1;
bbox[BOXBOTTOM] = by1;
// Trivial rejection // Trivial rejection
if (cx1 < bx1 && cx2 < bx1) if (cx1 < bbox[BOXLEFT] && cx2 < bbox[BOXLEFT])
return false; return false;
if (cx1 > bx2 && cx2 > bx2) if (cx1 > bbox[BOXRIGHT] && cx2 > bbox[BOXRIGHT])
return false; return false;
if (cy1 < by1 && cy2 < by1) if (cy1 < bbox[BOXBOTTOM] && cy2 < bbox[BOXBOTTOM])
return false; return false;
if (cy1 > by2 && cy2 > by2) if (cy1 > bbox[BOXTOP] && cy2 > bbox[BOXTOP])
return false; return false;
// Rats, guess we gotta check // 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; cy1 <<= FRACBITS;
cx2 <<= FRACBITS; cx2 <<= FRACBITS;
cy2 <<= FRACBITS; cy2 <<= FRACBITS;
bx1 <<= FRACBITS; bbox[BOXTOP] <<= FRACBITS;
by1 <<= FRACBITS; bbox[BOXBOTTOM] <<= FRACBITS;
bx2 <<= FRACBITS; bbox[BOXLEFT] <<= FRACBITS;
by2 <<= FRACBITS; bbox[BOXRIGHT] <<= FRACBITS;
boxline.v1 = &vbox;
testline.v1 = &vtest; testline.v1 = &vtest;
testline.v1->x = cx1; 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.dx = cx2 - cx1;
testline.dy = cy2 - cy1; testline.dy = cy2 - cy1;
// Test line against bottom edge of box if ((testline.dx > 0) ^ (testline.dy > 0))
boxline.v1->x = bx1; testline.slopetype = ST_NEGATIVE;
boxline.v1->y = by1; else
boxline.dx = bx2 - bx1; testline.slopetype = ST_POSITIVE;
boxline.dy = 0;
if (P_PointOnLineSide(cx1, cy1, &boxline) != P_PointOnLineSide(cx2, cy2, &boxline) return P_BoxOnLineSide(bbox, &testline) == -1;
&& 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;
} }
// //
@ -2435,11 +2403,8 @@ boolean P_SetupLevel(boolean skipprecip)
// chasecam on in chaos, race, coop // chasecam on in chaos, race, coop
// chasecam off in match, tag, capture the flag // chasecam off in match, tag, capture the flag
chase = (gametype == GT_RACE || gametype == GT_COMPETITION || gametype == GT_COOP chase = (gametype == GT_RACE || gametype == GT_COMPETITION || gametype == GT_COOP)
#ifdef CHAOSISNOTDEADYET || (maptol & TOL_2D);
|| gametype == GT_CHAOS
#endif
) || (maptol & TOL_2D);
if (!dedicated) if (!dedicated)
{ {

View file

@ -94,6 +94,7 @@ typedef struct
thinker_t **thinkers; thinker_t **thinkers;
} thinkerlist_t; } thinkerlist_t;
static void P_SearchForDisableLinedefs(void);
static void P_SpawnScrollers(void); static void P_SpawnScrollers(void);
static void P_SpawnFriction(void); static void P_SpawnFriction(void);
static void P_SpawnPushers(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. /** Adds a newly formed 3Dfloor structure to a sector's ffloors list.
* *
* \param sec Target sector. * \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; size_t i;
if (sec == sec2) 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) if (sec2->ceilingheight < sec2->floorheight)
{ {
@ -5312,9 +5327,6 @@ void T_LaserFlash(laserthink_t *flash)
ffloor_t *ffloor = flash->ffloor; ffloor_t *ffloor = flash->ffloor;
sector_t *sector = flash->sector; 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)) if (!ffloor || !(ffloor->flags & FF_EXISTS))
return; return;
@ -5409,6 +5421,10 @@ void P_SpawnSpecials(INT32 fromnetsave)
thinkerlist_t *secthinkers; thinkerlist_t *secthinkers;
thinker_t *th; 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. // Set the default gravity. Custom gravity overrides this setting.
gravity = FRACUNIT/2; gravity = FRACUNIT/2;
@ -5480,37 +5496,12 @@ void P_SpawnSpecials(INT32 fromnetsave)
curWeather = PRECIP_NONE; curWeather = PRECIP_NONE;
P_InitTagLists(); // Create xref tables for tags P_InitTagLists(); // Create xref tables for tags
P_SearchForDisableLinedefs(); // Disable linedefs are now allowed to disable *any* line
P_SpawnScrollers(); // Add generalized scrollers P_SpawnScrollers(); // Add generalized scrollers
P_SpawnFriction(); // Friction model using linedefs P_SpawnFriction(); // Friction model using linedefs
P_SpawnPushers(); // Pusher 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 // Look for thinkers that affect FOFs, and sort them by sector
secthinkers = Z_Calloc(numsectors * sizeof(thinkerlist_t), PU_STATIC, NULL); secthinkers = Z_Calloc(numsectors * sizeof(thinkerlist_t), PU_STATIC, NULL);
@ -5993,12 +5984,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
break; break;
case 160: // Float/bob platform case 160: // Float/bob platform
sec = sides[*lines[i].sidenum].sector - sectors; P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB, secthinkers);
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);
}
break; break;
case 170: // Crumbling platform case 170: // Crumbling platform
@ -6043,13 +6029,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
break; break;
case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits 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; 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); P_AddOldAirbob(lines[i].frontsector, lines + i, true);
break; break;
@ -6061,21 +6042,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
break; break;
case 178: // Crumbling platform that will float when it hits water case 178: // Crumbling platform that will float when it hits water
sec = sides[*lines[i].sidenum].sector - sectors; P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CRUMBLE|FF_FLOATBOB, secthinkers);
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);
}
break; break;
case 179: // Crumbling platform that will float when it hits water, but not return case 179: // Crumbling platform that will float when it hits water, but not return
sec = sides[*lines[i].sidenum].sector - sectors; P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE|FF_FLOATBOB|FF_NORETURN, secthinkers);
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);
}
break; break;
case 180: // Air bobbing platform that will crumble case 180: // Air bobbing platform that will crumble
@ -6158,14 +6129,13 @@ void P_SpawnSpecials(INT32 fromnetsave)
break; break;
case 202: // Fog 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; sec = sides[*lines[i].sidenum].sector - sectors;
// SoM: Because it's fog, check for an extra colormap and set // SoM: Because it's fog, check for an extra colormap and set
// the fog flag... // the fog flag...
if (sectors[sec].extra_colormap) if (sectors[sec].extra_colormap)
sectors[sec].extra_colormap->fog = 1; sectors[sec].extra_colormap->fog = 1;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
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);
break; break;
case 220: // Like opaque water, but not swimmable. (Good for snow effect on FOFs) case 220: // Like opaque water, but not swimmable. (Good for snow effect on FOFs)
@ -6195,12 +6165,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
break; break;
case 250: // Mario Block case 250: // Mario Block
sec = sides[*lines[i].sidenum].sector - sectors; P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO, secthinkers);
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);
}
break; break;
case 251: // A THWOMP! case 251: // A THWOMP!
@ -6247,13 +6212,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
break; break;
case 258: // Laser block 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 ;) // No longer totally disrupts netgames
EV_AddLaserThinker(&sectors[s], &sectors[sec], lines + i, secthinkers); for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
} EV_AddLaserThinker(&sectors[s], &sectors[sec], lines + i, secthinkers);
break; break;
case 259: // Make-Your-Own FOF! case 259: // Make-Your-Own FOF!
@ -7720,3 +7683,39 @@ static void P_SpawnPushers(void)
break; 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 // Check for pause or menu up in single player
if (paused || P_MenuActivePause()) if (paused || P_AutoPause())
return; return;
postimgtype = postimgtype2 = postimg_none; 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)); 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; return false;
if (modeattacking) return (menuactive || window_notinfocus);
return false;
return true;
} }
// //
@ -328,14 +330,10 @@ void P_GiveEmerald(boolean spawnObj)
// //
// P_ResetScore // P_ResetScore
// //
// This is called when your chain is reset. If in // This is called when your chain is reset.
// Chaos mode, it displays what chain you got.
void P_ResetScore(player_t *player) void P_ResetScore(player_t *player)
{ {
#ifdef CHAOSISNOTDEADYET // Formally a host for Chaos mode behavior
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
player->scoreadd = 0; player->scoreadd = 0;
} }
@ -2540,6 +2538,7 @@ static void P_DoClimbing(player_t *player)
thinker_t *think; thinker_t *think;
scroll_t *scroller; scroll_t *scroller;
angle_t sideangle; angle_t sideangle;
fixed_t dx, dy;
for (think = thinkercap.next; think != &thinkercap; think = think->next) 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) if (scroller->affectee != player->lastsidehit)
continue; continue;
if (scroller->accel)
{
dx = scroller->vdx;
dy = scroller->vdy;
}
else
{
dx = scroller->dx;
dy = scroller->dy;
}
if (cmd->forwardmove != 0) if (cmd->forwardmove != 0)
{ {
player->mo->momz += scroller->dy; player->mo->momz += dy;
climb = true; climb = true;
} }
else else
{ {
player->mo->momz = scroller->dy; player->mo->momz = dy;
climb = false; climb = false;
} }
@ -2569,12 +2579,12 @@ static void P_DoClimbing(player_t *player)
if (cmd->sidemove != 0) if (cmd->sidemove != 0)
{ {
P_Thrust(player->mo, sideangle, scroller->dx); P_Thrust(player->mo, sideangle, dx);
climb = true; climb = true;
} }
else else
{ {
P_InstaThrust(player->mo, sideangle, scroller->dx); P_InstaThrust(player->mo, sideangle, dx);
climb = false; 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 // P_DoTeeter
// //
@ -2826,18 +2955,18 @@ static void P_DoTeeter(player_t *player)
} }
} }
#ifdef POLYOBJECTS
// Polyobjects
{ {
INT32 bx, by, xl, xh, yl, yh; INT32 bx, by, xl, xh, yl, yh;
validcount++;
yh = (unsigned)(player->mo->y + player->mo->radius - bmaporgy)>>MAPBLOCKSHIFT; yh = (unsigned)(player->mo->y + player->mo->radius - bmaporgy)>>MAPBLOCKSHIFT;
yl = (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; xh = (unsigned)(player->mo->x + player->mo->radius - bmaporgx)>>MAPBLOCKSHIFT;
xl = (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 (by = yl; by <= yh; by++)
for (bx = xl; bx <= xh; bx++) 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 if (polybottom > player->mo->z + player->mo->height + tiptop
|| (polybottom < player->mo->z || (polybottom < player->mo->z
&& player->mo->z + player->mo->height < player->mo->ceilingz - tiptop)) && player->mo->z + player->mo->height < player->mo->ceilingz - tiptop))
{
teeter = true; teeter = true;
roverfloor = true;
}
else else
{ {
teeter = false; teeter = false;
roverfloor = true;
break; break;
} }
} }
@ -2920,16 +3045,12 @@ static void P_DoTeeter(player_t *player)
} }
if (polytop < player->mo->z - tiptop if (polytop < player->mo->z - tiptop
|| (polytop > player->mo->z + player->mo->height || (polytop > player->mo->z + player->mo->height
&& player->mo->z > player->mo->floorz + tiptop)) && player->mo->z > player->mo->floorz + tiptop))
{
teeter = true; teeter = true;
roverfloor = true;
}
else else
{ {
teeter = false; teeter = false;
roverfloor = true;
break; break;
} }
} }
@ -2937,8 +3058,27 @@ static void P_DoTeeter(player_t *player)
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
} }
} }
}
#endif #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 (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])) 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]]; py2 = bspcoord[checkcoord[boxpos][3]];
// check clip list for an open space // check clip list for an open space
angle1 = R_PointToAngle(px1, py1) - viewangle; angle1 = R_PointToAngle2(viewx>>1, viewy>>1, px1>>1, py1>>1) - viewangle;
angle2 = R_PointToAngle(px2, py2) - viewangle; angle2 = R_PointToAngle2(viewx>>1, viewy>>1, px2>>1, py2>>1) - viewangle;
span = angle1 - angle2; 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 *seg1 = *(const seg_t * const *)p1;
const seg_t *seg2 = *(const seg_t * const *)p2; 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? // 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)); dist1v1 = vxdist(seg1->v1);
dist2 = min(vxdist(seg2->v1), vxdist(seg2->v2)); 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! if (min(dist1v1, dist1v2) != min(dist2v1, dist2v2))
dist1 = max(vxdist(seg1->v1), vxdist(seg1->v2)); return min(dist1v1, dist1v2) - min(dist2v1, dist2v2);
dist2 = max(vxdist(seg2->v1), vxdist(seg2->v2));
{ // 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 #undef vxdist
#undef pdist
return dist1-dist2;
} }
// //
@ -835,6 +876,7 @@ static void R_Subsector(size_t num)
numffloors = 0; numffloors = 0;
ffloor[numffloors].plane = NULL; ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
if (frontsector->ffloors) if (frontsector->ffloors)
{ {
ffloor_t *rover; ffloor_t *rover;
@ -854,6 +896,7 @@ static void R_Subsector(size_t num)
} }
ffloor[numffloors].plane = NULL; ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
if (*rover->bottomheight <= frontsector->ceilingheight if (*rover->bottomheight <= frontsector->ceilingheight
&& *rover->bottomheight >= frontsector->floorheight && *rover->bottomheight >= frontsector->floorheight
&& ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES))
@ -872,6 +915,7 @@ static void R_Subsector(size_t num)
if (numffloors >= MAXFFLOORS) if (numffloors >= MAXFFLOORS)
break; break;
ffloor[numffloors].plane = NULL; ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
if (*rover->topheight >= frontsector->floorheight if (*rover->topheight >= frontsector->floorheight
&& *rover->topheight <= frontsector->ceilingheight && *rover->topheight <= frontsector->ceilingheight
&& ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) && ((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)); 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 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 (lump == LUMPERROR)
{ {
if (strcmp(name, SKYFLATNAME)) 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_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_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 = {"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_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}; 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; return;
CV_RegisterVar(&cv_precipdensity); CV_RegisterVar(&cv_precipdensity);
CV_RegisterVar(&cv_translucency);
CV_RegisterVar(&cv_drawdist); CV_RegisterVar(&cv_drawdist);
CV_RegisterVar(&cv_drawdist_nights); CV_RegisterVar(&cv_drawdist_nights);
CV_RegisterVar(&cv_drawdist_precip); 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_chasecam, cv_chasecam2;
extern consvar_t cv_flipcam, cv_flipcam2; extern consvar_t cv_flipcam, cv_flipcam2;
extern consvar_t cv_shadow, cv_shadowoffs; 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_precipdensity, cv_drawdist, cv_drawdist_nights, cv_drawdist_precip;
extern consvar_t cv_skybox; extern consvar_t cv_skybox;
extern consvar_t cv_tailspickup; extern consvar_t cv_tailspickup;

View file

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

View file

@ -1293,7 +1293,9 @@ static void R_ProjectSprite(mobj_t *thing)
vis->transmap = NULL; vis->transmap = NULL;
// specific translucency // 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 vis->transmap = ((tr_trans80-1)<<FF_TRANSSHIFT) + transtables; // because now the translucency is set through FF_TRANSMASK
else if (thing->frame & FF_TRANSMASK) else if (thing->frame & FF_TRANSMASK)
vis->transmap = (thing->frame & FF_TRANSMASK) - 0x10000 + transtables; vis->transmap = (thing->frame & FF_TRANSMASK) - 0x10000 + transtables;

View file

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

View file

@ -301,6 +301,7 @@ SDL_bool framebuffer = SDL_FALSE;
UINT8 keyboard_started = false; UINT8 keyboard_started = false;
#if !defined (DC)
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
{ {
//static char msg[] = "oh no! back to reality!\r\n"; //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"; sigmsg = "SIGILL - illegal instruction - invalid function image";
break; break;
case SIGFPE: case SIGFPE:
sigmsg = "SIGFPE - floating point exception"; sigmsg = "SIGFPE - mathematical exception";
break; break;
case SIGSEGV: case SIGSEGV:
sigmsg = "SIGSEGV - segment violation"; sigmsg = "SIGSEGV - segment violation";
@ -339,7 +340,7 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
sigmsg = sigdef; sigmsg = sigdef;
} }
I_OutputMsg("signal_handler() error: %s\n", sigmsg); I_OutputMsg("\nsignal_handler() error: %s\n", sigmsg);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
"Signal caught", "Signal caught",
@ -350,7 +351,6 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
I_Quit(); I_Quit();
} }
#if !defined (DC)
FUNCNORETURN static ATTRNORETURN void quit_handler(int num) FUNCNORETURN static ATTRNORETURN void quit_handler(int num)
{ {
signal(num, SIG_DFL); //default signal action signal(num, SIG_DFL); //default signal action
@ -743,24 +743,15 @@ static inline void I_ShutdownConsole(void){}
void I_StartupKeyboard (void) void I_StartupKeyboard (void)
{ {
#if !defined (DC) #if !defined (DC)
#ifdef SIGILL // If these defines don't exist,
signal(SIGILL , signal_handler); // then compilation would have failed above us...
#endif
#ifdef SIGINT
signal(SIGINT , quit_handler); signal(SIGINT , quit_handler);
#endif
#ifdef SIGSEGV
signal(SIGSEGV , signal_handler);
#endif
#ifdef SIGBREAK
signal(SIGBREAK , quit_handler); signal(SIGBREAK , quit_handler);
#endif
#ifdef SIGABRT
signal(SIGABRT , signal_handler);
#endif
#ifdef SIGTERM
signal(SIGTERM , quit_handler); signal(SIGTERM , quit_handler);
#endif signal(SIGILL , signal_handler);
signal(SIGSEGV , signal_handler);
signal(SIGABRT , signal_handler);
signal(SIGFPE , signal_handler);
#endif #endif
} }
@ -2375,62 +2366,38 @@ void I_Error(const char *error, ...)
} }
if (errorcount > 20) if (errorcount > 20)
{ {
#ifdef MAC_ALERT
va_start(argptr, error); va_start(argptr, error);
vsprintf(buffer, error, argptr); vsprintf(buffer, error, argptr);
va_end(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. // Implement message box with SDL_ShowSimpleMessageBox,
MacShowAlert("Recursive Error", buffer, "Quit", NULL, NULL); // which should fail gracefully if it can't put a message box up
#elif (defined (_WIN32) || (defined (_WIN32_WCE)) && !defined (__GNUC__)) && !defined (_XBOX) // on the target system
va_start(argptr,error); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
vsprintf(buffer, error, argptr); "SRB2 "VERSIONSTRING" Recursive Error",
va_end(argptr); buffer, NULL);
#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
W_Shutdown(); W_Shutdown();
#ifdef GP2X #ifdef GP2X
chdir("/usr/gp2x"); chdir("/usr/gp2x");
execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL);
#endif #endif
exit(-1); // recursive errors detected 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) shutdowning = true;
fflush(stderr);
#endif // 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.. M_SaveConfig(NULL); // save game config, cvars..
#ifndef NONET #ifndef NONET
D_SaveBan(); // save the ban list D_SaveBan(); // save the ban list
@ -2454,21 +2421,30 @@ void I_Error(const char *error, ...)
#ifndef _arch_dreamcast #ifndef _arch_dreamcast
SDL_Quit(); SDL_Quit();
#endif #endif
#ifdef MAC_ALERT
va_start(argptr, error); // Implement message box with SDL_ShowSimpleMessageBox,
vsprintf(buffer, error, argptr); // which should fail gracefully if it can't put a message box up
va_end(argptr); // on the target system
// 2004-03-03 AJR Since the Mac user is most likely double clicking to run the game, give them a panel. SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
MacShowAlert("Critical Error", buffer, "Quit", NULL, NULL); "SRB2 "VERSIONSTRING" Error",
#endif 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(); W_Shutdown();
#if defined (PARANOIA) && defined (__CYGWIN__) #if defined (PARANOIA) && defined (__CYGWIN__)
*(INT32 *)2 = 4; //Alam: Debug! *(INT32 *)2 = 4; //Alam: Debug!
#endif #endif
#ifdef GP2X #ifdef GP2X
chdir("/usr/gp2x"); chdir("/usr/gp2x");
execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL);
#endif #endif
exit(-1); exit(-1);
} }
@ -2534,6 +2510,7 @@ void I_ShutdownSystem(void)
#ifdef LOGMESSAGES #ifdef LOGMESSAGES
if (logstream) if (logstream)
{ {
I_OutputMsg("I_ShutdownSystem(): end of logstream.\n");
fclose(logstream); fclose(logstream);
logstream = NULL; logstream = NULL;
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -662,6 +662,32 @@ lumpnum_t W_GetNumForName(const char *name)
return i; 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... // Used by Lua. Case sensitive lump checking, quickly...
#include "fastcmp.h" #include "fastcmp.h"
UINT8 W_LumpExists(const char *name) 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 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_CheckNumForName(const char *name);
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR 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. UINT8 W_LumpExists(const char *name); // Lua uses this.
size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump); size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump);

View file

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

View file

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