- Update to ZDoom r1401:

- Made improvements so that the FOptionalMapinfoData class is easier to use.
- Moved the MF_INCHASE recursion check from A_Look() into A_Chase(). This
  lets A_Look() always put the actor into its see state. This problem could
  be heard by an Archvile's resurrectee playing its see sound but failing to
  enter its see state because it was called from A_Chase().
- Fixed: SBARINFO used different rounding modes for the background and
  foreground of the DrawBar command.
- Bumped MINSAVEVER to coincide with the new MAPINFO merge.
- Added a fflush() call after the logfile write in I_FatalError so that the
  error text is visible in the file while the error dialog is displayed.
- moved all code related to global ACS variables to p_acs.cpp where it belongs.
- fixed: The nextmap and nextsecret CCMDs need to call G_DeferedInitNew instead of G_InitNew.
- rewrote the MAPINFO parser:
  * split level_info_t::flags into 2 DWORDS so that I don't have to deal with 64 bit values later.
  * split off skill code into its own file
  * created a parser class for MAPINFO
  * replaced all uses of ReplaceString in level_info_t with FStrings and made the specialaction 
    data a TArray so that levelinfos can be handled without error prone maintenance functions.
  * split of parser code from g_level.cpp
  * const-ified parameters to F_StartFinale.
  * Changed how G_MaybeLookupLevelName works and made it return an FString.
  * removed 64 character limit on level names.
- Changed DECORATE replacements so that they aren't overridden by Dehacked.
- Fixed: The damage factor for 'normal' damage is supposed to be applied to
  all damage types that don't have a specific damage factor.
- Changed FMOD init() to allocate some virtual channels.
- Fixed clipping in D3DFB::DrawTextureV() for good by using a scissor test.
- Fixed: D3DFB::DrawTextureV() did not properly adjust the texture coordinate
  for lclip and rclip.
- Added weapdrop ccmd.
- Centered the compatibility mode option in the comptibility options menu.
- Added button mappings for 8 mouse buttons on SDL. It works with my system,
  but Linux being Linux, there are no guarantees that it's appropriate for
  other systems.
- Fixed: SDL input code did not generate GUI events for the mousewheel, so it
  could not be used to scroll the console buffer.
- Added Blzut3's statusbar maintenance patch.
- fixed sound origin of the Mage Wand's missile.
- Added APROP_Dropped actor property.
- Fixed: The compatmode CVAR needs CVAR_NOINITCALL so that the compatibility 
  flags don't get reset each start.
- Fixed: compatmode Doom(strict) was missing COMPAT_CROSSDROPOFF
- More GCC warning removal, the most egregious of which was the security
  vulnerability "format not a string literal and no format arguments".
- Changed the CMake script to search for fmod libraries by full name instead
  of assuming a symbolic link has been placed for the latest version. It can
  also find a non-installed copy of FMOD if it is placed local to the ZDoom
  source tree.
- Fixed: Some OPL state needs to be restored before calculating rhythm. Also,
  since only the rhythm section uses the RNG, it doesn't need to be advanced
  for the normal voice processing.


git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@297 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2009-02-05 00:06:30 +00:00
parent db550dc0b4
commit ad59f4da77
83 changed files with 3831 additions and 2617 deletions

View file

@ -1,3 +1,114 @@
February 5, 2009 (Changes by Graf Zahl)
- Made improvements so that the FOptionalMapinfoData class is easier to use.
February 3, 2009
- Moved the MF_INCHASE recursion check from A_Look() into A_Chase(). This
lets A_Look() always put the actor into its see state. This problem could
be heard by an Archvile's resurrectee playing its see sound but failing to
enter its see state because it was called from A_Chase().
- Fixed: SBARINFO used different rounding modes for the background and
foreground of the DrawBar command.
- Bumped MINSAVEVER to coincide with the new MAPINFO merge.
- Added a fflush() call after the logfile write in I_FatalError so that the
error text is visible in the file while the error dialog is displayed.
January 18, 2009 - February 3, 2009 (Changes by Graf Zahl)
- moved all code related to global ACS variables to p_acs.cpp where it belongs.
- fixed: The nextmap and nextsecret CCMDs need to call G_DeferedInitNew instead of G_InitNew.
- rewrote the MAPINFO parser:
* split level_info_t::flags into 2 DWORDS so that I don't have to deal with 64 bit values later.
* split off skill code into its own file
* created a parser class for MAPINFO
* replaced all uses of ReplaceString in level_info_t with FStrings and made the specialaction
data a TArray so that levelinfos can be handled without error prone maintenance functions.
* split of parser code from g_level.cpp
* const-ified parameters to F_StartFinale.
* Changed how G_MaybeLookupLevelName works and made it return an FString.
* removed 64 character limit on level names.
February 2, 2009
- Changed DECORATE replacements so that they aren't overridden by Dehacked.
February 2, 2009 (Changes by Graf Zahl)
- Fixed: The damage factor for 'normal' damage is supposed to be applied to
all damage types that don't have a specific damage factor.
January 31, 2009
- Changed FMOD init() to allocate some virtual channels.
- Fixed clipping in D3DFB::DrawTextureV() for good by using a scissor test.
January 30, 2009
- Fixed: D3DFB::DrawTextureV() did not properly adjust the texture coordinate
for lclip and rclip.
- Added weapdrop ccmd.
- Centered the compatibility mode option in the comptibility options menu.
- Added button mappings for 8 mouse buttons on SDL. It works with my system,
but Linux being Linux, there are no guarantees that it's appropriate for
other systems.
- Fixed: SDL input code did not generate GUI events for the mousewheel, so it
could not be used to scroll the console buffer.
January 30, 2009 (Changes by Graf Zahl)
- Added Blzut3's statusbar maintenance patch.
January 29, 2009 (Changes by Graf Zahl)
- fixed sound origin of the Mage Wand's missile.
January 28, 2009 (Changes by Graf Zahl)
- Added APROP_Dropped actor property.
- Fixed: The compatmode CVAR needs CVAR_NOINITCALL so that the compatibility
flags don't get reset each start.
- Fixed: compatmode Doom(strict) was missing COMPAT_CROSSDROPOFF
January 27, 2009
- More GCC warning removal, the most egregious of which was the security
vulnerability "format not a string literal and no format arguments".
- Changed the CMake script to search for fmod libraries by full name instead
of assuming a symbolic link has been placed for the latest version. It can
also find a non-installed copy of FMOD if it is placed local to the ZDoom
source tree.
January 26, 2009
- Fixed: Some OPL state needs to be restored before calculating rhythm. Also,
since only the rhythm section uses the RNG, it doesn't need to be advanced
for the normal voice processing.
January 25, 2009 (Changes by Graf Zahl)
- fixed some issues with P_FindFloorCeiling's coordinate processing.
- added a new compatmode CVAR which allows setting some generic compatibility
flag combinations:
Doom: sets the options needed to make most Doom.exe compatible map play without
errors.
Doom (strict): Same as above but sets a few more options. Please note that this
does not mean full Doom.exe behavior emulation.
Boom: Sets all options that consider differences between ZDoom and Boom.
ZDoom 2.0.63: Sets only the COMPATF_SOUNDTARGET option which is needed for
many older ZDoom maps.
- added new COMPAT_CROSSDROPOFF option to block monsters from being pushed over
dropoffs by damage kickback.
- fixed: AFastProjectile::Tick must call Effect only 8 times per tic, regardless
of the amount of steps taken.
- fixed: momentum checks in AFastProjectile did not use absolute values.
January 24, 2009
- Restored the rhythm section to fmopl.cpp and made some slight updates from
version 0.72 of MAME's fmopl.c. Also refactored CalcVoice so that the
original MAME structure is more visible.
- Removed the SoundChans bitfield from AActor, since it seems there are race
conditions I don't fully understand where it simply doesn't work.
- Removed BaseTime initialization from sdl/i_system.cpp as per Chris's
recommendation.
January 24, 2009 (Changes by Graf Zahl)
- Fixed: The sight checking code didn't initialize the myseethrough variable.
- Fixed: With COMPAT_TRACE switched on linedef actions on lines having
the same sector on both sides were not triggered.
January 23, 2009
- Set packet server as the default for four or more player games, and also the
default for three player games where the other players are not in the same
private IP range.
January 18, 2009 (Changes by Graf Zahl) January 18, 2009 (Changes by Graf Zahl)
- Added a CopyInfo function to FTexture that contains all code required to - Added a CopyInfo function to FTexture that contains all code required to
clone a texture. Used for creating warping textures. clone a texture. Used for creating warping textures.

View file

@ -625,6 +625,14 @@
RelativePath=".\src\g_level.cpp" RelativePath=".\src\g_level.cpp"
> >
</File> </File>
<File
RelativePath=".\src\g_mapinfo.cpp"
>
</File>
<File
RelativePath=".\src\g_skill.cpp"
>
</File>
<File <File
RelativePath=".\src\gameconfigfile.cpp" RelativePath=".\src\gameconfigfile.cpp"
> >

View file

@ -455,6 +455,8 @@ add_executable( zdoom WIN32
g_game.cpp g_game.cpp
g_hub.cpp g_hub.cpp
g_level.cpp g_level.cpp
g_mapinfo.cpp
g_skill.cpp
gameconfigfile.cpp gameconfigfile.cpp
gi.cpp gi.cpp
hu_scores.cpp hu_scores.cpp

View file

@ -1784,7 +1784,7 @@ void AM_Drawer ()
if (!automapactive) if (!automapactive)
return; return;
bool allmap = (level.flags & LEVEL_ALLMAP) != 0; bool allmap = (level.flags2 & LEVEL2_ALLMAP) != 0;
bool allthings = allmap && players[consoleplayer].mo->FindInventory<APowerScanner>() != NULL; bool allthings = allmap && players[consoleplayer].mo->FindInventory<APowerScanner>() != NULL;
AM_initColors (viewactive); AM_initColors (viewactive);

View file

@ -41,11 +41,13 @@
#define CREG_SECTION "__DATA,creg" #define CREG_SECTION "__DATA,creg"
#define GREG_SECTION "__DATA,greg" #define GREG_SECTION "__DATA,greg"
#define MREG_SECTION "__DATA,mreg" #define MREG_SECTION "__DATA,mreg"
#define MREG_SECTION "__DATA,yreg"
#else #else
#define AREG_SECTION "areg" #define AREG_SECTION "areg"
#define CREG_SECTION "creg" #define CREG_SECTION "creg"
#define GREG_SECTION "greg" #define GREG_SECTION "greg"
#define MREG_SECTION "mreg" #define MREG_SECTION "mreg"
#define GREG_SECTION "yreg"
#endif #endif
#endif #endif
@ -68,6 +70,10 @@ extern REGINFO GRegTail;
extern REGINFO MRegHead; extern REGINFO MRegHead;
extern REGINFO MRegTail; extern REGINFO MRegTail;
// List of MAPINFO map options
extern REGINFO YRegHead;
extern REGINFO YRegTail;
template<class T, REGINFO *_head, REGINFO *_tail> template<class T, REGINFO *_head, REGINFO *_tail>
class TAutoSegIteratorNoArrow class TAutoSegIteratorNoArrow
{ {

View file

@ -46,7 +46,7 @@
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma comment(linker, "/merge:.areg=.data /merge:.creg=.data /merge:.greg=.data /merge:.mreg=.data") #pragma comment(linker, "/merge:.areg=.data /merge:.creg=.data /merge:.greg=.data /merge:.mreg=.data /merge:.yreg=.data")
#pragma data_seg(".areg$a") #pragma data_seg(".areg$a")
void *ARegHead = 0; void *ARegHead = 0;
@ -60,6 +60,9 @@ void *GRegHead = 0;
#pragma data_seg(".mreg$a") #pragma data_seg(".mreg$a")
void *MRegHead = 0; void *MRegHead = 0;
#pragma data_seg(".yreg$a")
void *YRegHead = 0;
#pragma data_seg() #pragma data_seg()
// We want visual styles support under XP // We want visual styles support under XP
@ -87,6 +90,7 @@ void *ARegHead __attribute__((section(AREG_SECTION))) = 0;
void *CRegHead __attribute__((section(CREG_SECTION))) = 0; void *CRegHead __attribute__((section(CREG_SECTION))) = 0;
void *GRegHead __attribute__((section(GREG_SECTION))) = 0; void *GRegHead __attribute__((section(GREG_SECTION))) = 0;
void *MRegHead __attribute__((section(MREG_SECTION))) = 0; void *MRegHead __attribute__((section(MREG_SECTION))) = 0;
void *YRegHead __attribute__((section(YREG_SECTION))) = 0;
#elif #elif

View file

@ -49,6 +49,9 @@ void *GRegTail = 0;
#pragma data_seg(".mreg$z") #pragma data_seg(".mreg$z")
void *MRegTail = 0; void *MRegTail = 0;
#pragma data_seg(".yreg$z")
void *YRegTail = 0;
#pragma data_seg() #pragma data_seg()
@ -59,6 +62,7 @@ void *ARegTail __attribute__((section(AREG_SECTION))) = 0;
void *CRegTail __attribute__((section(CREG_SECTION))) = 0; void *CRegTail __attribute__((section(CREG_SECTION))) = 0;
void *GRegTail __attribute__((section(GREG_SECTION))) = 0; void *GRegTail __attribute__((section(GREG_SECTION))) = 0;
void *MRegTail __attribute__((section(MREG_SECTION))) = 0; void *MRegTail __attribute__((section(MREG_SECTION))) = 0;
void *YRegTail __attribute__((section(YREG_SECTION))) = 0;
#elif #elif

View file

@ -55,7 +55,7 @@ void FCajunMaster::ClearPlayer (int i, bool keepTeam)
if (bot) if (bot)
{ {
bot->inuse = false; bot->inuse = false;
bot->lastteam = keepTeam ? players[i].userinfo.team : TEAM_None; bot->lastteam = keepTeam ? players[i].userinfo.team : TEAM_NONE;
} }
players[i].~player_t(); players[i].~player_t();
::new(&players[i]) player_t; ::new(&players[i]) player_t;

View file

@ -332,7 +332,7 @@ bool FCajunMaster::SpawnBot (const char *name, int color)
{ {
strcat (concat, colors[bot_next_color]); strcat (concat, colors[bot_next_color]);
} }
if (TEAMINFO_IsValidTeam (thebot->lastteam)) if (TeamLibrary.IsValidTeam (thebot->lastteam))
{ // Keep the bot on the same team when switching levels { // Keep the bot on the same team when switching levels
mysnprintf (concat + strlen(concat), countof(concat) - strlen(concat), mysnprintf (concat + strlen(concat), countof(concat) - strlen(concat),
"\\team\\%d\n", thebot->lastteam); "\\team\\%d\n", thebot->lastteam);
@ -374,7 +374,7 @@ void FCajunMaster::DoAddBot (int bnum, char *info)
botingame[bnum] = true; botingame[bnum] = true;
if (teamplay) if (teamplay)
Printf ("%s joined the %s team\n", players[bnum].userinfo.netname, teams[players[bnum].userinfo.team].name.GetChars ()); Printf ("%s joined the %s team\n", players[bnum].userinfo.netname,Teams[players[bnum].userinfo.team].GetName ());
else else
Printf ("%s joined the game\n", players[bnum].userinfo.netname); Printf ("%s joined the game\n", players[bnum].userinfo.netname);
@ -592,17 +592,17 @@ bool FCajunMaster::LoadBots ()
if (IsNum (sc.String)) if (IsNum (sc.String))
{ {
teamnum = atoi (sc.String); teamnum = atoi (sc.String);
if (!TEAMINFO_IsValidTeam (teamnum)) if (!TeamLibrary.IsValidTeam (teamnum))
{ {
teamnum = TEAM_None; teamnum = TEAM_NONE;
} }
} }
else else
{ {
teamnum = TEAM_None; teamnum = TEAM_NONE;
for (int i = 0; i < int(teams.Size()); ++i) for (unsigned int i = 0; i < Teams.Size(); ++i)
{ {
if (stricmp (teams[i].name, sc.String) == 0) if (stricmp (Teams[i].GetName (), sc.String) == 0)
{ {
teamnum = i; teamnum = i;
break; break;
@ -638,7 +638,7 @@ bool FCajunMaster::LoadBots ()
appendinfo (newinfo->info, "255"); appendinfo (newinfo->info, "255");
} }
newinfo->next = bglobal.botinfo; newinfo->next = bglobal.botinfo;
newinfo->lastteam = TEAM_None; newinfo->lastteam = TEAM_NONE;
bglobal.botinfo = newinfo; bglobal.botinfo = newinfo;
bglobal.loaded_bots++; bglobal.loaded_bots++;
} }

View file

@ -482,7 +482,7 @@ CCMD (error)
if (argv.argc() > 1) if (argv.argc() > 1)
{ {
char *textcopy = copystring (argv[1]); char *textcopy = copystring (argv[1]);
I_Error (textcopy); I_Error ("%s", textcopy);
} }
else else
{ {
@ -495,7 +495,7 @@ CCMD (error_fatal)
if (argv.argc() > 1) if (argv.argc() > 1)
{ {
char *textcopy = copystring (argv[1]); char *textcopy = copystring (argv[1]);
I_FatalError (textcopy); I_FatalError ("%s", textcopy);
} }
else else
{ {
@ -858,7 +858,7 @@ CCMD(nextmap)
if (next != NULL && strncmp(next, "enDSeQ", 6)) if (next != NULL && strncmp(next, "enDSeQ", 6))
{ {
G_InitNew(next, false); G_DeferedInitNew(next, false);
} }
else else
{ {
@ -879,7 +879,7 @@ CCMD(nextsecret)
if (next != NULL && strncmp(next, "enDSeQ", 6)) if (next != NULL && strncmp(next, "enDSeQ", 6))
{ {
G_InitNew(next, false); G_DeferedInitNew(next, false);
} }
else else
{ {

View file

@ -1317,7 +1317,7 @@ void C_FullConsole ()
if (gamestate != GS_STARTUP) if (gamestate != GS_STARTUP)
{ {
gamestate = GS_FULLCONSOLE; gamestate = GS_FULLCONSOLE;
level.music = NULL; level.Music = "";
S_Start (); S_Start ();
P_FreeLevelData (); P_FreeLevelData ();
V_SetBlend (0,0,0,0); V_SetBlend (0,0,0,0);

View file

@ -2585,7 +2585,7 @@ void FinishDehPatch ()
AActor *defaults2 = GetDefaultByType (subclass); AActor *defaults2 = GetDefaultByType (subclass);
memcpy (defaults2, defaults1, sizeof(AActor)); memcpy (defaults2, defaults1, sizeof(AActor));
// Make a copy the replaced class's state labels // Make a copy of the replaced class's state labels
FStateDefinitions statedef; FStateDefinitions statedef;
statedef.MakeStateDefines(type); statedef.MakeStateDefines(type);
@ -2598,8 +2598,16 @@ void FinishDehPatch ()
// Use the DECORATE replacement feature to redirect all spawns // Use the DECORATE replacement feature to redirect all spawns
// of the original class to the new one. // of the original class to the new one.
FActorInfo *old_replacement = type->ActorInfo->Replacement;
type->ActorInfo->Replacement = subclass->ActorInfo; type->ActorInfo->Replacement = subclass->ActorInfo;
subclass->ActorInfo->Replacee = type->ActorInfo; subclass->ActorInfo->Replacee = type->ActorInfo;
// If this actor was already replaced by another actor, copy that
// replacement over to this item.
if (old_replacement != NULL)
{
subclass->ActorInfo->Replacement = old_replacement;
}
DPrintf ("%s replaces %s\n", subclass->TypeName.GetChars(), type->TypeName.GetChars()); DPrintf ("%s replaces %s\n", subclass->TypeName.GetChars(), type->TypeName.GetChars());
} }

View file

@ -523,7 +523,7 @@ CUSTOM_CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
i_compatflags = GetCompatibility(self); i_compatflags = GetCompatibility(self);
} }
CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_SERVERINFO) CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_SERVERINFO|CVAR_NOINITCALL)
{ {
int v; int v;
@ -542,7 +542,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
case 2: // same as 1 but stricter (NO_PASSMOBJ and INVISIBILITY are also set) case 2: // same as 1 but stricter (NO_PASSMOBJ and INVISIBILITY are also set)
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT| v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN| COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN|
COMPATF_DEHHEALTH|COMPATF_INVISIBILITY; COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF;
break; break;
case 3: case 3:
@ -2447,7 +2447,7 @@ void D_DoomMain (void)
} }
if (devparm) if (devparm)
{ {
Printf (GStrings("D_DEVSTR")); Printf ("%s", GStrings("D_DEVSTR"));
} }
#ifndef unix #ifndef unix
@ -2456,7 +2456,7 @@ void D_DoomMain (void)
// the user's home directory. // the user's home directory.
if (Args->CheckParm("-cdrom")) if (Args->CheckParm("-cdrom"))
{ {
Printf (GStrings("D_CDROM")); Printf ("%s", GStrings("D_CDROM"));
mkdir (CDROM_DIR, 0); mkdir (CDROM_DIR, 0);
} }
#endif #endif
@ -2521,9 +2521,9 @@ void D_DoomMain (void)
// Now that all textues have been loaded the crosshair can be initialized. // Now that all textues have been loaded the crosshair can be initialized.
crosshair.Callback (); crosshair.Callback ();
// [CW] Parse any TEAMINFO lumps // [CW] Parse any TEAMINFO lumps.
Printf ("TEAMINFO_Init: Load team definitions.\n"); Printf ("ParseTeamInfo: Load team definitions.\n");
TEAMINFO_Init (); TeamLibrary.ParseTeamInfo ();
FActorInfo::StaticInit (); FActorInfo::StaticInit ();

View file

@ -1963,7 +1963,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
BYTE who = ReadByte (stream); BYTE who = ReadByte (stream);
s = ReadString (stream); s = ReadString (stream);
if (((who & 1) == 0) || players[player].userinfo.team == TEAM_None) if (((who & 1) == 0) || players[player].userinfo.team == TEAM_NONE)
{ // Said to everyone { // Said to everyone
if (who & 2) if (who & 2)
{ {
@ -1997,7 +1997,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
case DEM_PRINT: case DEM_PRINT:
s = ReadString (stream); s = ReadString (stream);
Printf (s); Printf ("%s", s);
break; break;
case DEM_CENTERPRINT: case DEM_CENTERPRINT:

View file

@ -65,7 +65,7 @@ CVAR (Float, autoaim, 5000.f, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (String, skin, "base", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, skin, "base", CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Int, team, TEAM_None, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Int, team, TEAM_NONE, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Bool, neverswitchonpickup, false, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Bool, neverswitchonpickup, false, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Float, movebob, 0.25f, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Float, movebob, 0.25f, CVAR_USERINFO | CVAR_ARCHIVE);
@ -191,13 +191,13 @@ void D_GetPlayerColor (int player, float *h, float *s, float *v)
RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f, RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f,
h, s, v); h, s, v);
if (teamplay && TEAMINFO_IsValidTeam(info->team)) if (teamplay && TeamLibrary.IsValidTeam(info->team) && !Teams[info->team].GetAllowCustomPlayerColor ())
{ {
// In team play, force the player to use the team's hue // In team play, force the player to use the team's hue
// and adjust the saturation and value so that the team // and adjust the saturation and value so that the team
// hue is visible in the final color. // hue is visible in the final color.
float ts, tv; float ts, tv;
int tcolor = teams[info->team].playercolor; int tcolor = Teams[info->team].GetPlayerColor ();
RGBtoHSV (RPART(tcolor)/255.f, GPART(tcolor)/255.f, BPART(tcolor)/255.f, RGBtoHSV (RPART(tcolor)/255.f, GPART(tcolor)/255.f, BPART(tcolor)/255.f,
h, &ts, &tv); h, &ts, &tv);
@ -225,10 +225,10 @@ void D_PickRandomTeam (int player)
int D_PickRandomTeam () int D_PickRandomTeam ()
{ {
for (int i = 0; i < (signed)teams.Size (); i++) for (unsigned int i = 0; i < Teams.Size (); i++)
{ {
teams[i].present = 0; Teams[i].m_iPresent = 0;
teams[i].ties = 0; Teams[i].m_iTies = 0;
} }
int numTeams = 0; int numTeams = 0;
@ -238,9 +238,9 @@ int D_PickRandomTeam ()
{ {
if (playeringame[i]) if (playeringame[i])
{ {
if (TEAMINFO_IsValidTeam (players[i].userinfo.team)) if (TeamLibrary.IsValidTeam (players[i].userinfo.team))
{ {
if (teams[players[i].userinfo.team].present++ == 0) if (Teams[players[i].userinfo.team].m_iPresent++ == 0)
{ {
numTeams++; numTeams++;
} }
@ -252,36 +252,37 @@ int D_PickRandomTeam ()
{ {
do do
{ {
team = pr_pickteam() % teams.Size (); team = pr_pickteam() % Teams.Size ();
} while (teams[team].present != 0); } while (Teams[team].m_iPresent != 0);
} }
else else
{ {
int lowest = INT_MAX, lowestTie = 0, i; int lowest = INT_MAX, lowestTie = 0;
unsigned int i;
for (i = 0; i < (signed)teams.Size (); ++i) for (i = 0; i < Teams.Size (); ++i)
{ {
if (teams[i].present > 0) if (Teams[i].m_iPresent > 0)
{ {
if (teams[i].present < lowest) if (Teams[i].m_iPresent < lowest)
{ {
lowest = teams[i].present; lowest = Teams[i].m_iPresent;
lowestTie = 0; lowestTie = 0;
teams[0].ties = i; Teams[0].m_iTies = i;
} }
else if (teams[i].present == lowest) else if (Teams[i].m_iPresent == lowest)
{ {
teams[++lowestTie].ties = i; Teams[++lowestTie].m_iTies = i;
} }
} }
} }
if (lowestTie == 0) if (lowestTie == 0)
{ {
team = teams[0].ties; team = Teams[0].m_iTies;
} }
else else
{ {
team = teams[pr_pickteam() % (lowestTie+1)].ties; team = Teams[pr_pickteam() % (lowestTie+1)].m_iTies;
} }
} }
@ -292,7 +293,7 @@ static void UpdateTeam (int pnum, int team, bool update)
{ {
userinfo_t *info = &players[pnum].userinfo; userinfo_t *info = &players[pnum].userinfo;
if ((dmflags2 & DF2_NO_TEAM_SWITCH) && (alwaysapplydmflags || deathmatch) && TEAMINFO_IsValidTeam (info->team)) if ((dmflags2 & DF2_NO_TEAM_SWITCH) && (alwaysapplydmflags || deathmatch) && TeamLibrary.IsValidTeam (info->team))
{ {
Printf ("Team changing has been disabled!\n"); Printf ("Team changing has been disabled!\n");
return; return;
@ -300,21 +301,21 @@ static void UpdateTeam (int pnum, int team, bool update)
int oldteam; int oldteam;
if (!TEAMINFO_IsValidTeam (team)) if (!TeamLibrary.IsValidTeam (team))
{ {
team = TEAM_None; team = TEAM_NONE;
} }
oldteam = info->team; oldteam = info->team;
info->team = team; info->team = team;
if (teamplay && !TEAMINFO_IsValidTeam (info->team)) if (teamplay && !TeamLibrary.IsValidTeam (info->team))
{ // Force players onto teams in teamplay mode { // Force players onto teams in teamplay mode
info->team = D_PickRandomTeam (); info->team = D_PickRandomTeam ();
} }
if (update && oldteam != info->team) if (update && oldteam != info->team)
{ {
if (TEAMINFO_IsValidTeam (info->team)) if (TeamLibrary.IsValidTeam (info->team))
Printf ("%s joined the %s team\n", info->netname, teams[info->team].name.GetChars()); Printf ("%s joined the %s team\n", info->netname, Teams[info->team].GetName ());
else else
Printf ("%s is now a loner\n", info->netname); Printf ("%s is now a loner\n", info->netname);
} }
@ -324,13 +325,13 @@ static void UpdateTeam (int pnum, int team, bool update)
{ {
StatusBar->AttachToPlayer (&players[pnum]); StatusBar->AttachToPlayer (&players[pnum]);
} }
if (!TEAMINFO_IsValidTeam (info->team)) if (!TeamLibrary.IsValidTeam (info->team))
info->team = TEAM_None; info->team = TEAM_NONE;
} }
int D_GetFragCount (player_t *player) int D_GetFragCount (player_t *player)
{ {
if (!teamplay || !TEAMINFO_IsValidTeam (player->userinfo.team)) if (!teamplay || !TeamLibrary.IsValidTeam (player->userinfo.team))
{ {
return player->fragcount; return player->fragcount;
} }
@ -360,7 +361,7 @@ void D_SetupUserInfo ()
memset (&players[i].userinfo, 0, sizeof(userinfo_t)); memset (&players[i].userinfo, 0, sizeof(userinfo_t));
strncpy (coninfo->netname, name, MAXPLAYERNAME); strncpy (coninfo->netname, name, MAXPLAYERNAME);
if (teamplay && !TEAMINFO_IsValidTeam (team)) if (teamplay && !TeamLibrary.IsValidTeam (team))
{ {
coninfo->team = D_PickRandomTeam (); coninfo->team = D_PickRandomTeam ();
} }
@ -831,7 +832,7 @@ CCMD (playerinfo)
int i = atoi (argv[1]); int i = atoi (argv[1]);
userinfo_t *ui = &players[i].userinfo; userinfo_t *ui = &players[i].userinfo;
Printf ("Name: %s\n", ui->netname); Printf ("Name: %s\n", ui->netname);
Printf ("Team: %s (%d)\n", ui->team == TEAM_None ? "None" : teams[ui->team].name.GetChars(), ui->team); Printf ("Team: %s (%d)\n", ui->team == TEAM_NONE ? "None" : Teams[ui->team].GetName (), ui->team);
Printf ("Aimdist: %d\n", ui->aimdist); Printf ("Aimdist: %d\n", ui->aimdist);
Printf ("Color: %06x\n", ui->color); Printf ("Color: %06x\n", ui->color);
Printf ("Skin: %s (%d)\n", skins[ui->skin].name, ui->skin); Printf ("Skin: %s (%d)\n", skins[ui->skin].name, ui->skin);

View file

@ -253,7 +253,7 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size)
const PClass *existclass = FindClass(name); const PClass *existclass = FindClass(name);
// This is a placeholder so fill it in // This is a placeholder so fill it in
if (existclass != NULL && existclass->Size == -1) if (existclass != NULL && existclass->Size == (unsigned)-1)
{ {
type = const_cast<PClass*>(existclass); type = const_cast<PClass*>(existclass);
if (!IsDescendantOf(type->ParentClass)) if (!IsDescendantOf(type->ParentClass))

View file

@ -60,7 +60,7 @@ CUSTOM_CVAR (String, language, "auto", CVAR_ARCHIVE)
{ {
SetLanguageIDs (); SetLanguageIDs ();
GStrings.LoadStrings (false); GStrings.LoadStrings (false);
G_MaybeLookupLevelName (NULL); if (level.info != NULL) level.LevelName = level.info->LookupLevelName();
} }
// [RH] Network arbitrator // [RH] Network arbitrator

View file

@ -86,8 +86,8 @@ void F_AdvanceSlideshow ();
// //
// F_StartFinale // F_StartFinale
// //
void F_StartFinale (char *music, int musicorder, int cdtrack, unsigned int cdid, char *flat, char *text, void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText, bool ending) const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText, bool ending)
{ {
bool loopmusic = ending ? !(gameinfo.flags & GI_NOLOOPFINALEMUSIC) : true; bool loopmusic = ending ? !(gameinfo.flags & GI_NOLOOPFINALEMUSIC) : true;
gameaction = ga_nothing; gameaction = ga_nothing;
@ -1026,7 +1026,7 @@ void F_StartSlideshow ()
V_SetBlend (0,0,0,0); V_SetBlend (0,0,0,0);
// The slideshow is determined solely by the map you're on. // The slideshow is determined solely by the map you're on.
if (!multiplayer && level.flags & LEVEL_DEATHSLIDESHOW) if (!multiplayer && level.flags2 & LEVEL2_DEATHSLIDESHOW)
{ {
FinalePart = 14; FinalePart = 14;
} }
@ -1062,7 +1062,7 @@ void F_AdvanceSlideshow ()
{ {
case -99: case -99:
if (level.cdtrack == 0 || !S_ChangeCDMusic (level.cdtrack, level.cdid)) if (level.cdtrack == 0 || !S_ChangeCDMusic (level.cdtrack, level.cdid))
S_ChangeMusic (level.music, level.musicorder); S_ChangeMusic (level.Music, level.musicorder);
gamestate = GS_LEVEL; gamestate = GS_LEVEL;
wipegamestate = GS_LEVEL; wipegamestate = GS_LEVEL;
P_ResumeConversation (); P_ResumeConversation ();

View file

@ -42,8 +42,8 @@ void F_Ticker ();
void F_Drawer (); void F_Drawer ();
void F_StartFinale (char *music, int musicorder, int cdtrack, unsigned int cdid, char *flat, char *text, void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText, bool ending); const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText, bool ending);
void F_StartSlideshow (); void F_StartSlideshow ();

View file

@ -83,39 +83,22 @@ struct FFsOptions : public FOptionalMapinfoData
bool nocheckposition; bool nocheckposition;
}; };
static void ParseFunc(FScanner &sc, level_info_t *info) DEFINE_MAP_OPTION(fs_nocheckposition, false)
{ {
FName id = "fragglescript"; FFsOptions *opt = info->GetOptData<FFsOptions>("fragglescript");
FOptionalMapinfoData *dat = info->opdata;
while (dat && dat->identifier != id) dat = dat->Next; parse.ParseAssign();
if (!dat) dat = new FFsOptions; if (parse.CheckAssign())
dat->Next = info->opdata;
info->opdata = dat;
FFsOptions *opt = static_cast<FFsOptions*>(dat);
while (!sc.CheckString("}"))
{ {
sc.MustGetString(); parse.sc.MustGetNumber();
if (sc.Compare("nocheckposition")) opt->nocheckposition = !!parse.sc.Number;
{ }
if (!sc.CheckNumber()) opt->nocheckposition = false; else
else opt->nocheckposition = !!sc.Number; {
} opt->nocheckposition = true;
else
{
sc.ScriptError(NULL);
}
} }
} }
void AddFsMapinfoParser()
{
AddOptionalMapinfoParser("fragglescript", ParseFunc);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// Process the lump to strip all unneeded information from it // Process the lump to strip all unneeded information from it
@ -176,8 +159,7 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc)
while (*beg<=' ') beg++; while (*beg<=' ') beg++;
char * comm = strstr(beg, "//"); char * comm = strstr(beg, "//");
if (comm) *comm=0; if (comm) *comm=0;
strncpy(level.level_name, beg, 63); level.LevelName = beg;
level.level_name[63]=0;
} }
else if (sc.Compare("partime")) else if (sc.Compare("partime"))
{ {
@ -193,7 +175,7 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc)
sc.MustGetString(); sc.MustGetString();
if (!FS_ChangeMusic(sc.String)) if (!FS_ChangeMusic(sc.String))
{ {
S_ChangeMusic(level.music, level.musicorder); S_ChangeMusic(level.Music, level.musicorder);
} }
} }
else if (sc.Compare("skyname")) else if (sc.Compare("skyname"))
@ -211,7 +193,7 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc)
{ {
sc.MustGetStringName("="); sc.MustGetStringName("=");
sc.MustGetString(); sc.MustGetString();
ReplaceString(&level.info->exitpic, sc.String); level.info->ExitPic = sc.String;
} }
else if (sc.Compare("gravity")) else if (sc.Compare("gravity"))
{ {
@ -319,13 +301,9 @@ bool FScriptLoader::ParseInfo(MapData * map)
if (drownflag==-1) drownflag = ((level.flags&LEVEL_HEXENFORMAT) || fsglobal); if (drownflag==-1) drownflag = ((level.flags&LEVEL_HEXENFORMAT) || fsglobal);
if (!drownflag) level.airsupply=0; // Legacy doesn't to water damage. if (!drownflag) level.airsupply=0; // Legacy doesn't to water damage.
FName id = "fragglescript"; FFsOptions *opt = level.info->GetOptData<FFsOptions>("fragglescript", false);
FOptionalMapinfoData *dat = level.info->opdata; if (opt != NULL)
while (dat && dat->identifier != id) dat = dat->Next;
if (dat != NULL)
{ {
FFsOptions *opt = static_cast<FFsOptions*>(dat);
DFraggleThinker::ActiveThinker->nocheckposition = opt->nocheckposition; DFraggleThinker::ActiveThinker->nocheckposition = opt->nocheckposition;
} }
} }
@ -356,7 +334,7 @@ void T_LoadScripts(MapData *map)
// This code then then swaps 270 and 272 - but only if this is either Doom or Heretic and // This code then then swaps 270 and 272 - but only if this is either Doom or Heretic and
// the default translator is being used. // the default translator is being used.
// Custom translators will not be patched. // Custom translators will not be patched.
if ((gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Heretic) && level.info->translator == NULL && if ((gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Heretic) && level.info->Translator.IsEmpty() &&
!((level.flags&LEVEL_HEXENFORMAT)) && SimpleLineTranslations[272 - 2*HasScripts].special == FS_Execute) !((level.flags&LEVEL_HEXENFORMAT)) && SimpleLineTranslations[272 - 2*HasScripts].special == FS_Execute)
{ {
FLineTrans t = SimpleLineTranslations[270]; FLineTrans t = SimpleLineTranslations[270];

View file

@ -73,6 +73,7 @@
#include "cmdlib.h" #include "cmdlib.h"
#include "d_net.h" #include "d_net.h"
#include "d_event.h" #include "d_event.h"
#include "p_acs.h"
#include <zlib.h> #include <zlib.h>
@ -386,6 +387,11 @@ CCMD (invdrop)
if (players[consoleplayer].mo) SendItemDrop = players[consoleplayer].mo->InvSel; if (players[consoleplayer].mo) SendItemDrop = players[consoleplayer].mo->InvSel;
} }
CCMD (weapdrop)
{
SendItemDrop = players[consoleplayer].ReadyWeapon;
}
CCMD (drop) CCMD (drop)
{ {
if (argv.argc() > 1 && who != NULL) if (argv.argc() > 1 && who != NULL)
@ -1124,7 +1130,7 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, bool resetinventory
} }
} }
if (mode == FINISH_NoHub && !(level.flags & LEVEL_KEEPFULLINVENTORY)) if (mode == FINISH_NoHub && !(level.flags2 & LEVEL2_KEEPFULLINVENTORY))
{ // Reduce all owned (visible) inventory to 1 item each { // Reduce all owned (visible) inventory to 1 item each
for (item = p->mo->Inventory; item != NULL; item = item->Inventory) for (item = p->mo->Inventory; item != NULL; item = item->Inventory)
{ {
@ -1424,7 +1430,7 @@ static void G_QueueBody (AActor *body)
// //
void G_DoReborn (int playernum, bool freshbot) void G_DoReborn (int playernum, bool freshbot)
{ {
if (!multiplayer && !(level.flags & LEVEL_ALLOWRESPAWN)) if (!multiplayer && !(level.flags2 & LEVEL2_ALLOWRESPAWN))
{ {
if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars())) if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars()))
{ // Load game from the last point it was saved { // Load game from the last point it was saved
@ -1574,128 +1580,6 @@ bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn)
return true; return true;
} }
static void WriteVars (FILE *file, SDWORD *vars, size_t count, DWORD id)
{
size_t i, j;
for (i = 0; i < count; ++i)
{
if (vars[i] != 0)
break;
}
if (i < count)
{
// Find last non-zero var. Anything beyond the last stored variable
// will be zeroed at load time.
for (j = count-1; j > i; --j)
{
if (vars[j] != 0)
break;
}
FPNGChunkArchive arc (file, id);
for (i = 0; i <= j; ++i)
{
DWORD var = vars[i];
arc << var;
}
}
}
static void ReadVars (PNGHandle *png, SDWORD *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
size_t used = 0;
if (len != 0)
{
DWORD var;
size_t i;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
used = len / 4;
for (i = 0; i < used; ++i)
{
arc << var;
vars[i] = var;
}
png->File->ResetFilePtr();
}
if (used < count)
{
memset (&vars[used], 0, (count-used)*4);
}
}
static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int count, DWORD id)
{
unsigned int i, j;
// Find the first non-empty array.
for (i = 0; i < count; ++i)
{
if (vars[i].CountUsed() != 0)
break;
}
if (i < count)
{
// Find last non-empty array. Anything beyond the last stored array
// will be emptied at load time.
for (j = count-1; j > i; --j)
{
if (vars[j].CountUsed() != 0)
break;
}
FPNGChunkArchive arc (file, id);
arc.WriteCount (i);
arc.WriteCount (j);
for (; i <= j; ++i)
{
arc.WriteCount (vars[i].CountUsed());
FWorldGlobalArray::ConstIterator it(vars[i]);
const FWorldGlobalArray::Pair *pair;
while (it.NextPair (pair))
{
arc.WriteCount (pair->Key);
arc.WriteCount (pair->Value);
}
}
}
}
static void ReadArrayVars (PNGHandle *png, FWorldGlobalArray *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
unsigned int i, k;
for (i = 0; i < count; ++i)
{
vars[i].Clear ();
}
if (len != 0)
{
DWORD max, size;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
i = arc.ReadCount ();
max = arc.ReadCount ();
for (; i <= max; ++i)
{
size = arc.ReadCount ();
for (k = 0; k < size; ++k)
{
SDWORD key, val;
key = arc.ReadCount();
val = arc.ReadCount();
vars[i].Insert (key, val);
}
}
png->File->ResetFilePtr();
}
}
void G_DoLoadGame () void G_DoLoadGame ()
{ {
@ -1815,10 +1699,7 @@ void G_DoLoadGame ()
delete[] map; delete[] map;
savegamerestore = false; savegamerestore = false;
ReadVars (png, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r')); P_ReadACSVars(png);
ReadVars (png, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
ReadArrayVars (png, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
ReadArrayVars (png, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
NextSkill = -1; NextSkill = -1;
if (M_FindPNGChunk (png, MAKE_ID('s','n','X','t')) == 1) if (M_FindPNGChunk (png, MAKE_ID('s','n','X','t')) == 1)
@ -1980,7 +1861,7 @@ static void PutSaveComment (FILE *file)
// Get level name // Get level name
//strcpy (comment, level.level_name); //strcpy (comment, level.level_name);
mysnprintf(comment, countof(comment), "%s - %s", level.mapname, level.level_name); mysnprintf(comment, countof(comment), "%s - %s", level.mapname, level.LevelName.GetChars());
len = (WORD)strlen (comment); len = (WORD)strlen (comment);
comment[len] = '\n'; comment[len] = '\n';
@ -2064,10 +1945,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
FRandom::StaticWriteRNGState (stdfile); FRandom::StaticWriteRNGState (stdfile);
P_WriteACSDefereds (stdfile); P_WriteACSDefereds (stdfile);
WriteVars (stdfile, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r')); P_WriteACSVars(stdfile);
WriteVars (stdfile, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
WriteArrayVars (stdfile, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
WriteArrayVars (stdfile, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
if (NextSkill != -1) if (NextSkill != -1)
{ {
@ -2506,11 +2384,11 @@ void G_DoPlayDemo (void)
demo_p = demobuffer = NULL; demo_p = demobuffer = NULL;
if (singledemo) if (singledemo)
{ {
I_Error (eek); I_Error ("%s", eek);
} }
else else
{ {
Printf (PRINT_BOLD, eek); Printf (PRINT_BOLD, "%s", eek);
gameaction = ga_nothing; gameaction = ga_nothing;
} }
} }

View file

@ -72,7 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode)
S_Sound (mo, CHAN_BODY, "PotteryExplode", 1, ATTN_NORM); S_Sound (mo, CHAN_BODY, "PotteryExplode", 1, ATTN_NORM);
if (self->args[0]>=0 && self->args[0]<=255 && SpawnableThings[self->args[0]]) if (self->args[0]>=0 && self->args[0]<=255 && SpawnableThings[self->args[0]])
{ // Spawn an item { // Spawn an item
if (!((level.flags & LEVEL_NOMONSTERS) || (dmflags & DF_NO_MONSTERS)) if (!((level.flags2 & LEVEL2_NOMONSTERS) || (dmflags & DF_NO_MONSTERS))
|| !(GetDefaultByType (SpawnableThings[self->args[0]])->flags3 & MF3_ISMONSTER)) || !(GetDefaultByType (SpawnableThings[self->args[0]])->flags3 & MF3_ISMONSTER))
{ // Only spawn monsters if not -nomonsters { // Only spawn monsters if not -nomonsters
Spawn (SpawnableThings[self->args[0]], Spawn (SpawnableThings[self->args[0]],
@ -290,7 +290,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode)
} }
if (self->args[0]>=0 && self->args[0]<=255 && SpawnableThings[self->args[0]]) if (self->args[0]>=0 && self->args[0]<=255 && SpawnableThings[self->args[0]])
{ // Spawn an item { // Spawn an item
if (!((level.flags & LEVEL_NOMONSTERS) || (dmflags & DF_NO_MONSTERS)) if (!((level.flags2 & LEVEL2_NOMONSTERS) || (dmflags & DF_NO_MONSTERS))
|| !(GetDefaultByType (SpawnableThings[self->args[0]])->flags3 & MF3_ISMONSTER)) || !(GetDefaultByType (SpawnableThings[self->args[0]])->flags3 & MF3_ISMONSTER))
{ // Only spawn monsters if not -nomonsters { // Only spawn monsters if not -nomonsters
Spawn (SpawnableThings[self->args[0]], Spawn (SpawnableThings[self->args[0]],

View file

@ -127,17 +127,16 @@ void G_LeavingHub(int mode, cluster_info_t * cluster, wbstartstruct_t * wbs)
wbs->plyr[j].ssecret += hubdata[i].plyr[j].ssecret; wbs->plyr[j].ssecret += hubdata[i].plyr[j].ssecret;
} }
} }
if (cluster->clustername) if (cluster->ClusterName.IsNotEmpty())
{ {
if (cluster->flags & CLUSTER_LOOKUPNAME) if (cluster->flags & CLUSTER_LOOKUPNAME)
{ {
strncpy(level.level_name, GStrings(cluster->clustername), 64); level.LevelName = GStrings(cluster->ClusterName);
} }
else else
{ {
strncpy(level.level_name, cluster->clustername, 64); level.LevelName = cluster->ClusterName;
} }
level.level_name[63]=0;
} }
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -36,90 +36,166 @@
#include "doomtype.h" #include "doomtype.h"
#include "doomdef.h" #include "doomdef.h"
#include "autosegs.h"
#include "sc_man.h"
#define NUM_WORLDVARS 256 struct level_info_t;
#define NUM_GLOBALVARS 64 struct cluster_info_t;
class FScanner;
#define LEVEL_NOINTERMISSION UCONST64(0x00000001) #if defined(_MSC_VER)
#define LEVEL_NOINVENTORYBAR UCONST64(0x00000002) // This effects Doom only, since it's the only one without a standard inventory bar. #pragma data_seg(".yreg$u")
#define LEVEL_DOUBLESKY UCONST64(0x00000004) #pragma data_seg()
#define LEVEL_HASFADETABLE UCONST64(0x00000008) // Level uses Hexen's fadetable mapinfo to get fog
#define LEVEL_MAP07SPECIAL UCONST64(0x00000010) #define MSVC_YSEG __declspec(allocate(".yreg$u"))
#define LEVEL_BRUISERSPECIAL UCONST64(0x00000020) #define GCC_YSEG
#define LEVEL_CYBORGSPECIAL UCONST64(0x00000040) #else
#define LEVEL_SPIDERSPECIAL UCONST64(0x00000080) #define MSVC_YSEG
#define GCC_YSEG __attribute__((section(YREG_SECTION)))
#endif
#define LEVEL_SPECLOWERFLOOR UCONST64(0x00000100)
#define LEVEL_SPECOPENDOOR UCONST64(0x00000200)
#define LEVEL_SPECACTIONSMASK UCONST64(0x00000300)
#define LEVEL_MONSTERSTELEFRAG UCONST64(0x00000400) struct FMapInfoParser
#define LEVEL_ACTOWNSPECIAL UCONST64(0x00000800) {
#define LEVEL_SNDSEQTOTALCTRL UCONST64(0x00001000) enum EFormatType
#define LEVEL_FORCENOSKYSTRETCH UCONST64(0x00002000) {
FMT_Unknown,
FMT_Old,
FMT_New
};
#define LEVEL_CROUCH_NO UCONST64(0x00004000) FScanner sc;
#define LEVEL_JUMP_NO UCONST64(0x00008000) int format_type;
#define LEVEL_FREELOOK_NO UCONST64(0x00010000) bool HexenHack;
#define LEVEL_FREELOOK_YES UCONST64(0x00020000)
// The absence of both of the following bits means that this level does not FMapInfoParser()
// use falling damage (though damage can be forced with dmflags). {
#define LEVEL_FALLDMG_ZD UCONST64(0x00040000) // Level uses ZDoom's falling damage format_type = FMT_Unknown;
#define LEVEL_FALLDMG_HX UCONST64(0x00080000) // Level uses Hexen's falling damage HexenHack = false;
}
#define LEVEL_HEADSPECIAL UCONST64(0x00100000) // Heretic episode 1/4 bool ParseLookupName(FString &dest);
#define LEVEL_MINOTAURSPECIAL UCONST64(0x00200000) // Heretic episode 2/5 void ParseMusic(FString &name, int &order);
#define LEVEL_SORCERER2SPECIAL UCONST64(0x00400000) // Heretic episode 3 void ParseLumpOrTextureName(char *name);
#define LEVEL_SPECKILLMONSTERS UCONST64(0x00800000)
#define LEVEL_STARTLIGHTNING UCONST64(0x01000000) // Automatically start lightning void ParseCluster();
#define LEVEL_FILTERSTARTS UCONST64(0x02000000) // Apply mapthing filtering to player starts void ParseNextMap(char *mapname);
#define LEVEL_LOOKUPLEVELNAME UCONST64(0x04000000) // Level name is the name of a language string level_info_t *ParseMapHeader(level_info_t &defaultinfo);
#define LEVEL_HEXENFORMAT UCONST64(0x08000000) // Level uses the Hexen map format void ParseMapDefinition(level_info_t &leveldef);
void ParseEpisodeInfo ();
void ParseSkill ();
void ParseMapInfo (int lump, level_info_t &gamedefaults);
#define LEVEL_SWAPSKIES UCONST64(0x10000000) // Used by lightning void ParseOpenBrace();
#define LEVEL_NOALLIES UCONST64(0x20000000) // i.e. Inside Strife's front base bool ParseCloseBrace();
#define LEVEL_CHANGEMAPCHEAT UCONST64(0x40000000) // Don't display cluster messages bool CheckAssign();
#define LEVEL_VISITED UCONST64(0x80000000) // Used for intermission map void ParseAssign();
void MustParseAssign();
void ParseComma();
bool CheckNumber();
bool CheckFloat();
void SkipToNext();
};
#define LEVEL_DEATHSLIDESHOW UCONST64(0x100000000) // Slideshow on death #define DEFINE_MAP_OPTION(name, old) \
#define LEVEL_ALLMAP UCONST64(0x200000000) // The player picked up a map on this level static void MapOptHandler_##name(FMapInfoParser &parse, level_info_t *info); \
static FMapOptInfo MapOpt_##name = \
{ #name, MapOptHandler_##name, old }; \
MSVC_YSEG FMapOptInfo *mapopt_##name GCC_YSEG = &MapOpt_##name; \
static void MapOptHandler_##name(FMapInfoParser &parse, level_info_t *info)
#define LEVEL_LAXMONSTERACTIVATION UCONST64(0x400000000) // Monsters can open doors depending on the door speed
#define LEVEL_LAXACTIVATIONMAPINFO UCONST64(0x800000000) // LEVEL_LAXMONSTERACTIVATION is not a default.
#define LEVEL_MISSILESACTIVATEIMPACT UCONST64(0x1000000000) // Missiles are the activators of SPAC_IMPACT events, not their shooters struct FMapOptInfo
#define LEVEL_FROZEN UCONST64(0x2000000000) // Game is frozen by a TimeFreezer {
const char *name;
void (*handler) (FMapInfoParser &parse, level_info_t *levelinfo);
bool old;
};
#define LEVEL_KEEPFULLINVENTORY UCONST64(0x4000000000) // doesn't reduce the amount of inventory items to 1 enum ELevelFlags
{
LEVEL_NOINTERMISSION = 0x00000001,
LEVEL_NOINVENTORYBAR = 0x00000002, // This effects Doom only, since it's the only one without a standard inventory bar.
LEVEL_DOUBLESKY = 0x00000004,
LEVEL_HASFADETABLE = 0x00000008, // Level uses Hexen's fadetable mapinfo to get fog
#define LEVEL_MUSICDEFINED UCONST64(0x8000000000) // a marker to disable the $map command in SNDINFO for this map LEVEL_MAP07SPECIAL = 0x00000010,
#define LEVEL_MONSTERFALLINGDAMAGE UCONST64(0x10000000000) LEVEL_BRUISERSPECIAL = 0x00000020,
#define LEVEL_CLIPMIDTEX UCONST64(0x20000000000) LEVEL_CYBORGSPECIAL = 0x00000040,
#define LEVEL_WRAPMIDTEX UCONST64(0x40000000000) LEVEL_SPIDERSPECIAL = 0x00000080,
#define LEVEL_CHECKSWITCHRANGE UCONST64(0x80000000000) LEVEL_SPECLOWERFLOOR = 0x00000100,
LEVEL_SPECOPENDOOR = 0x00000200,
LEVEL_SPECACTIONSMASK = 0x00000300,
#define LEVEL_PAUSE_MUSIC_IN_MENUS UCONST64(0x100000000000) LEVEL_MONSTERSTELEFRAG = 0x00000400,
#define LEVEL_TOTALINFIGHTING UCONST64(0x200000000000) LEVEL_ACTOWNSPECIAL = 0x00000800,
#define LEVEL_NOINFIGHTING UCONST64(0x400000000000) LEVEL_SNDSEQTOTALCTRL = 0x00001000,
LEVEL_FORCENOSKYSTRETCH = 0x00002000,
#define LEVEL_NOMONSTERS UCONST64(0x800000000000) LEVEL_CROUCH_NO = 0x00004000,
#define LEVEL_INFINITE_FLIGHT UCONST64(0x1000000000000) LEVEL_JUMP_NO = 0x00008000,
LEVEL_FREELOOK_NO = 0x00010000,
LEVEL_FREELOOK_YES = 0x00020000,
#define LEVEL_ALLOWRESPAWN UCONST64(0x2000000000000) // The absence of both of the following bits means that this level does not
// use falling damage (though damage can be forced with dmflags,.
LEVEL_FALLDMG_ZD = 0x00040000, // Level uses ZDoom's falling damage
LEVEL_FALLDMG_HX = 0x00080000, // Level uses Hexen's falling damage
#define LEVEL_FORCETEAMPLAYON UCONST64(0x4000000000000) LEVEL_HEADSPECIAL = 0x00100000, // Heretic episode 1/4
#define LEVEL_FORCETEAMPLAYOFF UCONST64(0x8000000000000) LEVEL_MINOTAURSPECIAL = 0x00200000, // Heretic episode 2/5
LEVEL_SORCERER2SPECIAL = 0x00400000, // Heretic episode 3
LEVEL_SPECKILLMONSTERS = 0x00800000,
#define LEVEL_CONV_SINGLE_UNFREEZE UCONST64(0x10000000000000) LEVEL_STARTLIGHTNING = 0x01000000, // Automatically start lightning
#define LEVEL_RAILINGHACK UCONST64(0x20000000000000) // but UDMF requires them to be separate to have more control LEVEL_FILTERSTARTS = 0x02000000, // Apply mapthing filtering to player starts
#define LEVEL_DUMMYSWITCHES UCONST64(0x40000000000000) LEVEL_LOOKUPLEVELNAME = 0x04000000, // Level name is the name of a language string
#define LEVEL_HEXENHACK UCONST64(0x80000000000000) // Level was defined in a Hexen style MAPINFO LEVEL_HEXENFORMAT = 0x08000000, // Level uses the Hexen map format
#define LEVEL_SMOOTHLIGHTING UCONST64(0x100000000000000) // Level uses the smooth lighting feature. LEVEL_SWAPSKIES = 0x10000000, // Used by lightning
LEVEL_NOALLIES = 0x20000000, // i.e. Inside Strife's front base
LEVEL_CHANGEMAPCHEAT = 0x40000000, // Don't display cluster messages
LEVEL_VISITED = 0x80000000, // Used for intermission map
// The flags QWORD is now split into 2 DWORDs
LEVEL2_DEATHSLIDESHOW = 0x00000001, // Slideshow on death
LEVEL2_ALLMAP = 0x00000002, // The player picked up a map on this level
LEVEL2_LAXMONSTERACTIVATION = 0x00000004, // Monsters can open doors depending on the door speed
LEVEL2_LAXACTIVATIONMAPINFO = 0x00000008, // LEVEL_LAXMONSTERACTIVATION is not a default.
LEVEL2_MISSILESACTIVATEIMPACT = 0x00000010, // Missiles are the activators of SPAC_IMPACT events, not their shooters
LEVEL2_FROZEN = 0x00000020, // Game is frozen by a TimeFreezer
LEVEL2_KEEPFULLINVENTORY = 0x00000040, // doesn't reduce the amount of inventory items to 1
LEVEL2_MUSICDEFINED = 0x00000080, // a marker to disable the $map command in SNDINFO for this map
LEVEL2_MONSTERFALLINGDAMAGE = 0x00000100,
LEVEL2_CLIPMIDTEX = 0x00000200,
LEVEL2_WRAPMIDTEX = 0x00000400,
LEVEL2_CHECKSWITCHRANGE = 0x00000800,
LEVEL2_PAUSE_MUSIC_IN_MENUS = 0x00001000,
LEVEL2_TOTALINFIGHTING = 0x00002000,
LEVEL2_NOINFIGHTING = 0x00004000,
LEVEL2_NOMONSTERS = 0x00008000,
LEVEL2_INFINITE_FLIGHT = 0x00010000,
LEVEL2_ALLOWRESPAWN = 0x00020000,
LEVEL2_FORCETEAMPLAYON = 0x00040000,
LEVEL2_FORCETEAMPLAYOFF = 0x00080000,
LEVEL2_CONV_SINGLE_UNFREEZE = 0x00100000,
LEVEL2_RAILINGHACK = 0x00200000, // but UDMF requires them to be separate to have more control
LEVEL2_DUMMYSWITCHES = 0x00400000,
LEVEL2_HEXENHACK = 0x00800000, // Level was defined in a Hexen style MAPINFO
LEVEL2_SMOOTHLIGHTING = 0x01000000, // Level uses the smooth lighting feature.
};
struct acsdefered_t; struct acsdefered_t;
@ -129,7 +205,6 @@ struct FSpecialAction
FName Type; // this is initialized before the actors... FName Type; // this is initialized before the actors...
BYTE Action; BYTE Action;
int Args[5]; // must allow 16 bit tags for 666 & 667! int Args[5]; // must allow 16 bit tags for 666 & 667!
FSpecialAction *Next;
}; };
class FCompressedMemFile; class FCompressedMemFile;
@ -137,9 +212,6 @@ class DScroller;
class FScanner; class FScanner;
struct level_info_t; struct level_info_t;
typedef void (*MIParseFunc)(FScanner &sc, level_info_t *info);
void AddOptionalMapinfoParser(const char *keyword, MIParseFunc parsefunc);
struct FOptionalMapinfoData struct FOptionalMapinfoData
{ {
@ -150,6 +222,18 @@ struct FOptionalMapinfoData
virtual FOptionalMapinfoData *Clone() const = 0; virtual FOptionalMapinfoData *Clone() const = 0;
}; };
struct FOptionalMapinfoDataPtr
{
FOptionalMapinfoData *Ptr;
FOptionalMapinfoDataPtr() throw() : Ptr(NULL) {}
~FOptionalMapinfoDataPtr() { if (Ptr!=NULL) delete Ptr; }
FOptionalMapinfoDataPtr(const FOptionalMapinfoDataPtr &p) throw() : Ptr(p.Ptr->Clone()) {}
FOptionalMapinfoDataPtr &operator= (FOptionalMapinfoDataPtr &p) throw() { Ptr = p.Ptr->Clone(); return *this; }
};
typedef TMap<FName, FOptionalMapinfoDataPtr> FOptData;
struct level_info_t struct level_info_t
{ {
char mapname[9]; char mapname[9];
@ -161,13 +245,13 @@ struct level_info_t
int cluster; int cluster;
int partime; int partime;
int sucktime; int sucktime;
QWORD flags; DWORD flags;
char *music; DWORD flags2;
char *level_name; FString Music;
FString LevelName;
char fadetable[9]; char fadetable[9];
SBYTE WallVertLight, WallHorizLight; SBYTE WallVertLight, WallHorizLight;
char f1[9]; char f1[9];
// TheDefaultLevelInfo initializes everything above this line.
int musicorder; int musicorder;
FCompressedMemFile *snapshot; FCompressedMemFile *snapshot;
DWORD snapshotVer; DWORD snapshotVer;
@ -185,27 +269,61 @@ struct level_info_t
int airsupply; int airsupply;
DWORD compatflags; DWORD compatflags;
DWORD compatmask; DWORD compatmask;
char *translator; // for converting Doom-format linedef and sector types. FString Translator; // for converting Doom-format linedef and sector types.
// Redirection: If any player is carrying the specified item, then // Redirection: If any player is carrying the specified item, then
// you go to the RedirectMap instead of this one. // you go to the RedirectMap instead of this one.
FName RedirectType; FName RedirectType;
char RedirectMap[9]; char RedirectMap[9];
char *enterpic; FString EnterPic;
char *exitpic; FString ExitPic;
char *intermusic; FString InterMusic;
int intermusicorder; int intermusicorder;
char *soundinfo; FString SoundInfo;
char *sndseq; FString SndSeq;
char bordertexture[9]; char bordertexture[9];
float teamdamage; float teamdamage;
FSpecialAction * specialactions; FOptData optdata;
FOptionalMapinfoData *opdata;
TArray<FSpecialAction> specialactions;
level_info_t()
{
Reset();
}
~level_info_t()
{
ClearSnapshot();
ClearDefered();
}
void Reset();
bool isValid();
FString LookupLevelName ();
void ClearSnapshot();
void ClearDefered();
level_info_t *CheckLevelRedirect ();
template<class T>
T *GetOptData(FName id, bool create = true)
{
FOptionalMapinfoDataPtr *pdat = optdata.CheckKey(id);
if (pdat != NULL)
{
return static_cast<T*>(pdat->Ptr);
}
else if (create)
{
T *newobj = new T;
optdata[id].Ptr = newobj;
return newobj;
}
else return NULL;
}
}; };
// [RH] These get zeroed every tic and are updated by thinkers. // [RH] These get zeroed every tic and are updated by thinkers.
@ -231,17 +349,18 @@ struct FLevelLocals
int clusterflags; int clusterflags;
int levelnum; int levelnum;
int lumpnum; int lumpnum;
char level_name[64]; // the descriptive name (Outer Base, etc) FString LevelName;
char mapname[256]; // the server name (base1, etc) char mapname[256]; // the server name (base1, etc)
char nextmap[9]; // go here when fraglimit is hit char nextmap[9]; // go here when fraglimit is hit
char secretmap[9]; // map to go to when used secret exit char secretmap[9]; // map to go to when used secret exit
QWORD flags; DWORD flags;
DWORD flags2;
DWORD fadeto; // The color the palette fades to (usually black) DWORD fadeto; // The color the palette fades to (usually black)
DWORD outsidefog; // The fog for sectors with sky ceilings DWORD outsidefog; // The fog for sectors with sky ceilings
char *music; FString Music;
int musicorder; int musicorder;
int cdtrack; int cdtrack;
unsigned int cdid; unsigned int cdid;
@ -313,14 +432,17 @@ struct cluster_info_t
{ {
int cluster; int cluster;
char finaleflat[9]; char finaleflat[9];
char *exittext; FString ExitText;
char *entertext; FString EnterText;
char *messagemusic; FString MessageMusic;
int musicorder; int musicorder;
int flags; int flags;
int cdtrack; int cdtrack;
char *clustername; FString ClusterName;
unsigned int cdid; unsigned int cdid;
void Reset();
}; };
// Cluster flags // Cluster flags
@ -331,25 +453,12 @@ struct cluster_info_t
#define CLUSTER_LOOKUPEXITTEXT 0x00000010 // Exit text is the name of a language string #define CLUSTER_LOOKUPEXITTEXT 0x00000010 // Exit text is the name of a language string
#define CLUSTER_LOOKUPENTERTEXT 0x00000020 // Enter text is the name of a language string #define CLUSTER_LOOKUPENTERTEXT 0x00000020 // Enter text is the name of a language string
#define CLUSTER_LOOKUPNAME 0x00000040 // Name is the name of a language string #define CLUSTER_LOOKUPNAME 0x00000040 // Name is the name of a language string
#define CLUSTER_LOOKUPCLUSTERNAME 0x00000080 // Cluster name is the name of a language string
extern FLevelLocals level; extern FLevelLocals level;
extern TArray<level_info_t> wadlevelinfos; extern TArray<level_info_t> wadlevelinfos;
extern TArray<cluster_info_t> wadclusterinfos;
extern SDWORD ACS_WorldVars[NUM_WORLDVARS];
extern SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
struct InitIntToZero
{
void Init(int &v)
{
v = 0;
}
};
typedef TMap<SDWORD, SDWORD, THashTraits<SDWORD>, InitIntToZero> FWorldGlobalArray;
extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
extern bool savegamerestore; extern bool savegamerestore;
@ -382,8 +491,6 @@ void G_InitLevelLocals (void);
void G_AirControlChanged (); void G_AirControlChanged ();
const char *G_MaybeLookupLevelName (level_info_t *level);
cluster_info_t *FindClusterInfo (int cluster); cluster_info_t *FindClusterInfo (int cluster);
level_info_t *FindLevelInfo (const char *mapname); level_info_t *FindLevelInfo (const char *mapname);
level_info_t *FindLevelByNum (int num); level_info_t *FindLevelByNum (int num);
@ -392,9 +499,9 @@ level_info_t *CheckLevelRedirect (level_info_t *info);
FString CalcMapName (int episode, int level); FString CalcMapName (int episode, int level);
void G_ParseMapInfo (void); void G_ParseMapInfo (void);
void G_UnloadMapInfo ();
void G_ClearSnapshots (void); void G_ClearSnapshots (void);
void P_RemoveDefereds ();
void G_SnapshotLevel (void); void G_SnapshotLevel (void);
void G_UnSnapshotLevel (bool keepPlayers); void G_UnSnapshotLevel (bool keepPlayers);
struct PNGHandle; struct PNGHandle;

1850
src/g_mapinfo.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -951,7 +951,7 @@ void APowerFlight::InitEffect ()
void APowerFlight::Tick () void APowerFlight::Tick ()
{ {
// The Wings of Wrath only expire in multiplayer and non-hub games // The Wings of Wrath only expire in multiplayer and non-hub games
if (!multiplayer && (level.flags & LEVEL_INFINITE_FLIGHT)) if (!multiplayer && (level.flags2 & LEVEL2_INFINITE_FLIGHT))
{ {
assert(EffectTics < INT_MAX); // I can't see a game lasting nearly two years, but... assert(EffectTics < INT_MAX); // I can't see a game lasting nearly two years, but...
EffectTics++; EffectTics++;
@ -1364,7 +1364,7 @@ void APowerTimeFreezer::InitEffect( )
// Make sure the effect starts and ends on an even tic. // Make sure the effect starts and ends on an even tic.
if ((level.time & 1) == 0) if ((level.time & 1) == 0)
{ {
level.flags |= LEVEL_FROZEN; level.flags2 |= LEVEL2_FROZEN;
} }
else else
{ {
@ -1395,9 +1395,9 @@ void APowerTimeFreezer::DoEffect( )
|| (( EffectTics > 2*32 && EffectTics <= 3*32 ) && ((EffectTics + 1) & 7) != 0 ) || (( EffectTics > 2*32 && EffectTics <= 3*32 ) && ((EffectTics + 1) & 7) != 0 )
|| (( EffectTics > 32 && EffectTics <= 2*32 ) && ((EffectTics + 1) & 3) != 0 ) || (( EffectTics > 32 && EffectTics <= 2*32 ) && ((EffectTics + 1) & 3) != 0 )
|| (( EffectTics > 0 && EffectTics <= 1*32 ) && ((EffectTics + 1) & 1) != 0 )) || (( EffectTics > 0 && EffectTics <= 1*32 ) && ((EffectTics + 1) & 1) != 0 ))
level.flags |= LEVEL_FROZEN; level.flags2 |= LEVEL2_FROZEN;
else else
level.flags &= ~LEVEL_FROZEN; level.flags2 &= ~LEVEL2_FROZEN;
} }
//=========================================================================== //===========================================================================
@ -1411,7 +1411,7 @@ void APowerTimeFreezer::EndEffect( )
int ulIdx; int ulIdx;
// Allow other actors to move about freely once again. // Allow other actors to move about freely once again.
level.flags &= ~LEVEL_FROZEN; level.flags2 &= ~LEVEL2_FROZEN;
// Also, turn the music back on. // Also, turn the music back on.
S_ResumeSound( ); S_ResumeSound( );

View file

@ -1707,7 +1707,7 @@ IMPLEMENT_CLASS (AMapRevealer)
bool AMapRevealer::TryPickup (AActor *&toucher) bool AMapRevealer::TryPickup (AActor *&toucher)
{ {
level.flags |= LEVEL_ALLMAP; level.flags2 |= LEVEL2_ALLMAP;
GoAwayAndDie (); GoAwayAndDie ();
return true; return true;
} }

View file

@ -147,17 +147,9 @@ struct SBarInfo
static void Load(); static void Load();
}; };
#define NUM_SCRIPTS 5
#define SCRIPT_CUSTOM 0 #define SCRIPT_CUSTOM 0
#define SCRIPT_DOOM 1 #define SCRIPT_DEFAULT 1
// The next ones shouldn't be used... yet extern SBarInfo *SBarInfoScript[2];
#define SCRIPT_HERETIC 2
#define SCRIPT_HEXEN 3
#define SCRIPT_STRIFE 4
// Converts GAME_x to it's script number
#define GETSBARINFOSCRIPT(game) \
(game & GAME_DoomChex) ? SCRIPT_DOOM : (game == GAME_Heretic ? SCRIPT_HERETIC : (game == GAME_Hexen ? SCRIPT_HEXEN : (game == GAME_Strife ? SCRIPT_STRIFE : SCRIPT_CUSTOM)))
extern SBarInfo *SBarInfoScript[5];
// Enums used between the parser and the display // Enums used between the parser and the display

View file

@ -56,6 +56,7 @@
#include "a_strifeglobal.h" #include "a_strifeglobal.h"
#include "g_level.h" #include "g_level.h"
#include "v_palette.h" #include "v_palette.h"
#include "p_acs.h"
static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic. static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic.

View file

@ -46,16 +46,9 @@
#include "gi.h" #include "gi.h"
#include "i_system.h" #include "i_system.h"
#include "g_level.h" #include "g_level.h"
#include "p_acs.h"
SBarInfo *SBarInfoScript[NUM_SCRIPTS] = {NULL,NULL,NULL,NULL,NULL}; SBarInfo *SBarInfoScript[2] = {NULL,NULL};
static const char *DefaultScriptNames[NUM_SCRIPTS] =
{
"SBARINFO", //Custom
"sbarinfo/doom.txt",
NULL, //Heretic
NULL, //Hexen
NULL //Strife
};
static const char *SBarInfoTopLevel[] = static const char *SBarInfoTopLevel[] =
{ {
@ -114,7 +107,7 @@ static const char *SBarInfoRoutineLevel[] =
static void FreeSBarInfoScript() static void FreeSBarInfoScript()
{ {
for(int i = 0;i < NUM_SCRIPTS;i++) for(int i = 0;i < 2;i++)
{ {
if (SBarInfoScript[i] != NULL) if (SBarInfoScript[i] != NULL)
{ {
@ -126,28 +119,25 @@ static void FreeSBarInfoScript()
void SBarInfo::Load() void SBarInfo::Load()
{ {
Printf ("ParseSBarInfo: Loading default status bar definitions.\n"); if(gameinfo.statusbar != NULL)
for(int i = 1;i < NUM_SCRIPTS;i++) // Read in default bars if they exist
{ {
if(DefaultScriptNames[i] != NULL) int lump = Wads.CheckNumForFullName(gameinfo.statusbar, true);
if(lump != -1)
{ {
int lump = Wads.CheckNumForFullName(DefaultScriptNames[i], true); Printf ("ParseSBarInfo: Loading default status bar definition.\n");
if(lump != -1) if(SBarInfoScript[SCRIPT_DEFAULT] == NULL)
{ SBarInfoScript[SCRIPT_DEFAULT] = new SBarInfo(lump);
if(SBarInfoScript[i] == NULL) else
SBarInfoScript[i] = new SBarInfo(lump); SBarInfoScript[SCRIPT_DEFAULT]->ParseSBarInfo(lump);
else
SBarInfoScript[i]->ParseSBarInfo(lump);
}
} }
} }
if(Wads.CheckNumForName(DefaultScriptNames[SCRIPT_CUSTOM]) != -1) if(Wads.CheckNumForName("SBARINFO") != -1)
{ {
Printf ("ParseSBarInfo: Loading custom status bar definition.\n"); Printf ("ParseSBarInfo: Loading custom status bar definition.\n");
int lastlump, lump; int lastlump, lump;
lastlump = 0; lastlump = 0;
while((lump = Wads.FindLump(DefaultScriptNames[SCRIPT_CUSTOM], &lastlump)) != -1) while((lump = Wads.FindLump("SBARINFO", &lastlump)) != -1)
{ {
if(SBarInfoScript[SCRIPT_CUSTOM] == NULL) if(SBarInfoScript[SCRIPT_CUSTOM] == NULL)
SBarInfoScript[SCRIPT_CUSTOM] = new SBarInfo(lump); SBarInfoScript[SCRIPT_CUSTOM] = new SBarInfo(lump);

View file

@ -875,7 +875,7 @@ void DrawHUD()
} }
} }
mysnprintf(printstr, countof(printstr), "%s: %s", level.mapname, level.level_name); mysnprintf(printstr, countof(printstr), "%s: %s", level.mapname, level.LevelName.GetChars());
screen->DrawText(SmallFont, hudcolor_titl, 1, hudheight-fonth-1, printstr, screen->DrawText(SmallFont, hudcolor_titl, 1, hudheight-fonth-1, printstr,
DTA_KeepRatio, true, DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE); DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE);

View file

@ -1242,11 +1242,11 @@ void DBaseStatusBar::Draw (EHudState state)
{ {
i = mysnprintf (line, countof(line), "%s: ", level.mapname); i = mysnprintf (line, countof(line), "%s: ", level.mapname);
} }
line[i] = TEXTCOLOR_ESCAPE; FString mapname;
line[i+1] = CR_GREY + 'A';
strcpy (&line[i+2], level.level_name); mapname.Format("%c%c%s", TEXTCOLOR_ESCAPE, CR_GREY + 'A', level.LevelName.GetChars());
screen->DrawText (SmallFont, highlight, screen->DrawText (SmallFont, highlight,
(SCREENWIDTH - SmallFont->StringWidth (line)*CleanXfac)/2, y, line, (SCREENWIDTH - SmallFont->StringWidth (mapname)*CleanXfac)/2, y, mapname,
DTA_CleanNoMove, true, TAG_DONE); DTA_CleanNoMove, true, TAG_DONE);
if (!deathmatch) if (!deathmatch)

354
src/g_skill.cpp Normal file
View file

@ -0,0 +1,354 @@
/*
** g_skill.cpp
** Skill level handling
**
**---------------------------------------------------------------------------
** Copyright 2008-2009 Christoph Oelckers
** Copyright 2008-2009 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include <ctype.h>
#include "doomstat.h"
#include "g_level.h"
#include "g_game.h"
#include "gi.h"
#include "templates.h"
#include "v_font.h"
TArray<FSkillInfo> AllSkills;
//==========================================================================
//
// ParseSkill
//
//==========================================================================
void FMapInfoParser::ParseSkill ()
{
FSkillInfo skill;
skill.AmmoFactor = FRACUNIT;
skill.DoubleAmmoFactor = 2*FRACUNIT;
skill.DropAmmoFactor = -1;
skill.DamageFactor = FRACUNIT;
skill.FastMonsters = false;
skill.DisableCheats = false;
skill.EasyBossBrain = false;
skill.AutoUseHealth = false;
skill.RespawnCounter = 0;
skill.RespawnLimit = 0;
skill.Aggressiveness = FRACUNIT;
skill.SpawnFilter = 0;
skill.ACSReturn = AllSkills.Size();
skill.MenuNameIsLump = false;
skill.MustConfirm = false;
skill.Shortcut = 0;
skill.TextColor = "";
sc.MustGetString();
skill.Name = sc.String;
ParseOpenBrace();
while (sc.GetString ())
{
if (sc.Compare ("ammofactor"))
{
ParseAssign();
sc.MustGetFloat ();
skill.AmmoFactor = FLOAT2FIXED(sc.Float);
}
else if (sc.Compare ("doubleammofactor"))
{
ParseAssign();
sc.MustGetFloat ();
skill.DoubleAmmoFactor = FLOAT2FIXED(sc.Float);
}
else if (sc.Compare ("dropammofactor"))
{
ParseAssign();
sc.MustGetFloat ();
skill.DropAmmoFactor = FLOAT2FIXED(sc.Float);
}
else if (sc.Compare ("damagefactor"))
{
ParseAssign();
sc.MustGetFloat ();
skill.DamageFactor = FLOAT2FIXED(sc.Float);
}
else if (sc.Compare ("fastmonsters"))
{
skill.FastMonsters = true;
}
else if (sc.Compare ("disablecheats"))
{
skill.DisableCheats = true;
}
else if (sc.Compare ("easybossbrain"))
{
skill.EasyBossBrain = true;
}
else if (sc.Compare("autousehealth"))
{
skill.AutoUseHealth = true;
}
else if (sc.Compare("respawntime"))
{
ParseAssign();
sc.MustGetFloat ();
skill.RespawnCounter = int(sc.Float*TICRATE);
}
else if (sc.Compare("respawnlimit"))
{
ParseAssign();
sc.MustGetNumber ();
skill.RespawnLimit = sc.Number;
}
else if (sc.Compare("Aggressiveness"))
{
ParseAssign();
sc.MustGetFloat ();
skill.Aggressiveness = FRACUNIT - FLOAT2FIXED(clamp(sc.Float, 0.,1.));
}
else if (sc.Compare("SpawnFilter"))
{
ParseAssign();
if (sc.CheckNumber())
{
if (sc.Number > 0) skill.SpawnFilter |= (1<<(sc.Number-1));
}
else
{
sc.MustGetString ();
if (sc.Compare("baby")) skill.SpawnFilter |= 1;
else if (sc.Compare("easy")) skill.SpawnFilter |= 2;
else if (sc.Compare("normal")) skill.SpawnFilter |= 4;
else if (sc.Compare("hard")) skill.SpawnFilter |= 8;
else if (sc.Compare("nightmare")) skill.SpawnFilter |= 16;
}
}
else if (sc.Compare("ACSReturn"))
{
ParseAssign();
sc.MustGetNumber ();
skill.ACSReturn = sc.Number;
}
else if (sc.Compare("Name"))
{
ParseAssign();
sc.MustGetString ();
skill.MenuName = sc.String;
skill.MenuNameIsLump = false;
}
else if (sc.Compare("PlayerClassName"))
{
ParseAssign();
sc.MustGetString ();
FName pc = sc.String;
ParseComma();
sc.MustGetString ();
skill.MenuNamesForPlayerClass[pc]=sc.String;
}
else if (sc.Compare("PicName"))
{
ParseAssign();
sc.MustGetString ();
skill.MenuName = sc.String;
skill.MenuNameIsLump = true;
}
else if (sc.Compare("MustConfirm"))
{
ParseAssign();
skill.MustConfirm = true;
if (sc.CheckToken(TK_StringConst))
{
skill.MustConfirmText = sc.String;
}
}
else if (sc.Compare("Key"))
{
ParseAssign();
sc.MustGetString();
skill.Shortcut = tolower(sc.String[0]);
}
else if (sc.Compare("TextColor"))
{
ParseAssign();
sc.MustGetString();
skill.TextColor.Format("[%s]", sc.String);
}
else if (!ParseCloseBrace())
{
// Unknown
sc.ScriptMessage("Unknown property '%s' found in skill definition\n", sc.String);
SkipToNext();
}
else
{
break;
}
}
for(unsigned int i = 0; i < AllSkills.Size(); i++)
{
if (AllSkills[i].Name == skill.Name)
{
AllSkills[i] = skill;
return;
}
}
AllSkills.Push(skill);
}
//==========================================================================
//
//
//
//==========================================================================
int G_SkillProperty(ESkillProperty prop)
{
if (AllSkills.Size() > 0)
{
switch(prop)
{
case SKILLP_AmmoFactor:
if (dmflags2 & DF2_YES_DOUBLEAMMO)
{
return AllSkills[gameskill].DoubleAmmoFactor;
}
return AllSkills[gameskill].AmmoFactor;
case SKILLP_DropAmmoFactor:
return AllSkills[gameskill].DropAmmoFactor;
case SKILLP_DamageFactor:
return AllSkills[gameskill].DamageFactor;
case SKILLP_FastMonsters:
return AllSkills[gameskill].FastMonsters || (dmflags & DF_FAST_MONSTERS);
case SKILLP_Respawn:
if (dmflags & DF_MONSTERS_RESPAWN && AllSkills[gameskill].RespawnCounter==0)
return TICRATE * (gameinfo.gametype != GAME_Strife ? 12 : 16);
return AllSkills[gameskill].RespawnCounter;
case SKILLP_RespawnLimit:
return AllSkills[gameskill].RespawnLimit;
case SKILLP_Aggressiveness:
return AllSkills[gameskill].Aggressiveness;
case SKILLP_DisableCheats:
return AllSkills[gameskill].DisableCheats;
case SKILLP_AutoUseHealth:
return AllSkills[gameskill].AutoUseHealth;
case SKILLP_EasyBossBrain:
return AllSkills[gameskill].EasyBossBrain;
case SKILLP_SpawnFilter:
return AllSkills[gameskill].SpawnFilter;
case SKILLP_ACSReturn:
return AllSkills[gameskill].ACSReturn;
}
}
return 0;
}
//==========================================================================
//
//
//
//==========================================================================
void G_VerifySkill()
{
if (gameskill >= (int)AllSkills.Size())
gameskill = AllSkills.Size()-1;
else if (gameskill < 0)
gameskill = 0;
}
//==========================================================================
//
//
//
//==========================================================================
FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other)
{
Name = other.Name;
AmmoFactor = other.AmmoFactor;
DoubleAmmoFactor = other.DoubleAmmoFactor;
DropAmmoFactor = other.DropAmmoFactor;
DamageFactor = other.DamageFactor;
FastMonsters = other.FastMonsters;
DisableCheats = other.DisableCheats;
AutoUseHealth = other.AutoUseHealth;
EasyBossBrain = other.EasyBossBrain;
RespawnCounter= other.RespawnCounter;
RespawnLimit= other.RespawnLimit;
Aggressiveness= other.Aggressiveness;
SpawnFilter = other.SpawnFilter;
ACSReturn = other.ACSReturn;
MenuName = other.MenuName;
MenuNamesForPlayerClass = other.MenuNamesForPlayerClass;
MenuNameIsLump = other.MenuNameIsLump;
MustConfirm = other.MustConfirm;
MustConfirmText = other.MustConfirmText;
Shortcut = other.Shortcut;
TextColor = other.TextColor;
return *this;
}
//==========================================================================
//
//
//
//==========================================================================
int FSkillInfo::GetTextColor() const
{
if (TextColor.IsEmpty())
{
return CR_UNTRANSLATED;
}
const BYTE *cp = (const BYTE *)TextColor.GetChars();
int color = V_ParseFontColor(cp, 0, 0);
if (color == CR_UNDEFINED)
{
Printf("Undefined color '%s' in definition of skill %s\n", TextColor.GetChars(), Name.GetChars());
color = CR_UNTRANSLATED;
}
return color;
}

View file

@ -106,7 +106,7 @@ IMPLEMENT_CLASS (AScanner)
bool AScanner::Use (bool pickup) bool AScanner::Use (bool pickup)
{ {
if (!(level.flags & LEVEL_ALLMAP)) if (!(level.flags2 & LEVEL2_ALLMAP))
{ {
if (Owner->CheckLocalView (consoleplayer)) if (Owner->CheckLocalView (consoleplayer))
{ {

View file

@ -101,6 +101,7 @@ gameinfo_t HexenGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"BagOfHolding", // Hexen doesn't have a backpack so use Heretic's. "BagOfHolding", // Hexen doesn't have a backpack so use Heretic's.
NULL,
}; };
gameinfo_t HexenDKGameInfo = gameinfo_t HexenDKGameInfo =
@ -134,6 +135,7 @@ gameinfo_t HexenDKGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"BagOfHolding", "BagOfHolding",
NULL,
}; };
gameinfo_t HereticGameInfo = gameinfo_t HereticGameInfo =
@ -167,6 +169,7 @@ gameinfo_t HereticGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"BagOfHolding", "BagOfHolding",
NULL,
}; };
gameinfo_t HereticSWGameInfo = gameinfo_t HereticSWGameInfo =
@ -200,6 +203,7 @@ gameinfo_t HereticSWGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"BagOfHolding", "BagOfHolding",
NULL,
}; };
gameinfo_t SharewareGameInfo = gameinfo_t SharewareGameInfo =
@ -233,6 +237,7 @@ gameinfo_t SharewareGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"Backpack", "Backpack",
"sbarinfo/doom.txt",
}; };
gameinfo_t RegisteredGameInfo = gameinfo_t RegisteredGameInfo =
@ -266,6 +271,7 @@ gameinfo_t RegisteredGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"Backpack", "Backpack",
"sbarinfo/doom.txt",
}; };
gameinfo_t ChexGameInfo = gameinfo_t ChexGameInfo =
@ -299,6 +305,7 @@ gameinfo_t ChexGameInfo =
MAKERGB(63,125,57), MAKERGB(63,125,57),
MAKERGB(95,175,87), MAKERGB(95,175,87),
"ZorchPack", "ZorchPack",
"sbarinfo/doom.txt",
}; };
gameinfo_t Chex3GameInfo = gameinfo_t Chex3GameInfo =
@ -332,6 +339,7 @@ gameinfo_t Chex3GameInfo =
MAKERGB(63,125,57), MAKERGB(63,125,57),
MAKERGB(95,175,87), MAKERGB(95,175,87),
"ZorchPack", "ZorchPack",
"sbarinfo/doom.txt",
}; };
gameinfo_t RetailGameInfo = gameinfo_t RetailGameInfo =
@ -365,6 +373,7 @@ gameinfo_t RetailGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"Backpack", "Backpack",
"sbarinfo/doom.txt",
}; };
gameinfo_t CommercialGameInfo = gameinfo_t CommercialGameInfo =
@ -398,6 +407,7 @@ gameinfo_t CommercialGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"Backpack", "Backpack",
"sbarinfo/doom.txt",
}; };
gameinfo_t PlutoniaGameInfo = gameinfo_t PlutoniaGameInfo =
@ -431,6 +441,7 @@ gameinfo_t PlutoniaGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"Backpack", "Backpack",
"sbarinfo/doom.txt",
}; };
gameinfo_t TNTGameInfo = gameinfo_t TNTGameInfo =
@ -464,6 +475,7 @@ gameinfo_t TNTGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"Backpack", "Backpack",
"sbarinfo/doom.txt",
}; };
gameinfo_t StrifeGameInfo = gameinfo_t StrifeGameInfo =
@ -497,6 +509,7 @@ gameinfo_t StrifeGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"AmmoSatchel", "AmmoSatchel",
NULL,
}; };
gameinfo_t StrifeTeaserGameInfo = gameinfo_t StrifeTeaserGameInfo =
@ -530,6 +543,7 @@ gameinfo_t StrifeTeaserGameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"AmmoSatchel", "AmmoSatchel",
NULL,
}; };
gameinfo_t StrifeTeaser2GameInfo = gameinfo_t StrifeTeaser2GameInfo =
@ -563,4 +577,5 @@ gameinfo_t StrifeTeaser2GameInfo =
MAKERGB(104,0,0), MAKERGB(104,0,0),
MAKERGB(255,0,0), MAKERGB(255,0,0),
"AmmoSatchel", "AmmoSatchel",
NULL,
}; };

View file

@ -122,6 +122,7 @@ typedef struct
DWORD defaultbloodcolor; DWORD defaultbloodcolor;
DWORD defaultbloodparticlecolor; DWORD defaultbloodparticlecolor;
const char *backpacktype; const char *backpacktype;
const char *statusbar;
} gameinfo_t; } gameinfo_t;
extern gameinfo_t gameinfo; extern gameinfo_t gameinfo;

View file

@ -93,7 +93,6 @@ void gl_InitSpecialTextures()
glpart = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart.png"), FTexture::TEX_MiscPatch); glpart = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart.png"), FTexture::TEX_MiscPatch);
mirrortexture = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/mirror.png"), FTexture::TEX_MiscPatch); mirrortexture = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/mirror.png"), FTexture::TEX_MiscPatch);
gllight = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/gllight.png"), FTexture::TEX_MiscPatch); gllight = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/gllight.png"), FTexture::TEX_MiscPatch);
//atterm(DeleteGLTextures);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -221,88 +220,73 @@ struct FGLROptions : public FOptionalMapinfoData
FVector3 skyrotatevector; FVector3 skyrotatevector;
}; };
static void ParseFunc(FScanner &sc, level_info_t *info) DEFINE_MAP_OPTION(fogdensity, false)
{ {
FName id = "gl_renderer"; FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
FOptionalMapinfoData *dat = info->opdata; parse.ParseAssign();
parse.sc.MustGetNumber();
opt->fogdensity = parse.sc.Number;
}
while (dat && dat->identifier != id) dat = dat->Next; DEFINE_MAP_OPTION(outsidefogdensity, false)
if (!dat) {
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
parse.ParseAssign();
parse.sc.MustGetNumber();
opt->outsidefogdensity = parse.sc.Number;
}
DEFINE_MAP_OPTION(skyfog, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
parse.ParseAssign();
parse.sc.MustGetNumber();
opt->skyfog = parse.sc.Number;
}
DEFINE_MAP_OPTION(lightmode, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
parse.ParseAssign();
parse.sc.MustGetNumber();
opt->lightmode = BYTE(parse.sc.Number);
}
DEFINE_MAP_OPTION(nocoloredspritelighting, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
if (parse.CheckAssign())
{ {
dat = new FGLROptions; parse.sc.MustGetNumber();
dat->Next = info->opdata; opt->nocoloredspritelighting = !!parse.sc.Number;
info->opdata = dat;
} }
else
FGLROptions *opt = static_cast<FGLROptions*>(dat);
while (!sc.CheckString("}"))
{ {
sc.MustGetString(); opt->nocoloredspritelighting = true;
if (sc.Compare("fogdensity"))
{
sc.MustGetNumber();
opt->fogdensity = sc.Number;
}
else if (sc.Compare("outsidefogdensity"))
{
sc.MustGetNumber();
opt->outsidefogdensity = sc.Number;
}
else if (sc.Compare("skyfog"))
{
sc.MustGetNumber();
opt->skyfog = sc.Number;
}
else if (sc.Compare("lightmode"))
{
sc.MustGetNumber();
opt->lightmode = BYTE(sc.Number);
}
else if (sc.Compare("nocoloredspritelighting"))
{
if (sc.CheckNumber())
{
opt->nocoloredspritelighting = !!sc.Number;
}
else
{
opt->nocoloredspritelighting = true;
}
}
else if (sc.Compare("skyrotate"))
{
sc.MustGetFloat();
opt->skyrotatevector.X = (float)sc.Float;
sc.MustGetFloat();
opt->skyrotatevector.Y = (float)sc.Float;
sc.MustGetFloat();
opt->skyrotatevector.Z = (float)sc.Float;
opt->skyrotatevector.MakeUnit();
}
else
{
sc.ScriptError("Unknown keyword %s", sc.String);
}
} }
} }
void gl_AddMapinfoParser() DEFINE_MAP_OPTION(skyrotate, false)
{ {
AddOptionalMapinfoParser("gl_renderer", ParseFunc); FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
parse.ParseAssign();
parse.sc.MustGetFloat();
opt->skyrotatevector.X = (float)parse.sc.Float;
parse.sc.MustGetFloat();
opt->skyrotatevector.Y = (float)parse.sc.Float;
parse.sc.MustGetFloat();
opt->skyrotatevector.Z = (float)parse.sc.Float;
opt->skyrotatevector.MakeUnit();
} }
static void InitGLRMapinfoData() static void InitGLRMapinfoData()
{ {
FName id = "gl_renderer"; FGLROptions *opt = level.info->GetOptData<FGLROptions>("gl_renderer", false);
FOptionalMapinfoData *dat = level.info->opdata;
while (dat && dat->identifier != id) dat = dat->Next; if (opt != NULL)
if (dat != NULL)
{ {
FGLROptions *opt = static_cast<FGLROptions*>(dat);
gl_SetFogParams(opt->fogdensity, level.info->outsidefog, opt->outsidefogdensity, opt->skyfog); gl_SetFogParams(opt->fogdensity, level.info->outsidefog, opt->outsidefogdensity, opt->skyfog);
glset.map_lightmode = opt->lightmode; glset.map_lightmode = opt->lightmode;
glset.map_nocoloredspritelighting = opt->nocoloredspritelighting; glset.map_nocoloredspritelighting = opt->nocoloredspritelighting;
glset.skyrotatevector = opt->skyrotatevector; glset.skyrotatevector = opt->skyrotatevector;

View file

@ -514,7 +514,7 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf,
// [BB] To interpolate at more than 35 fps we take tic fractions into account. // [BB] To interpolate at more than 35 fps we take tic fractions into account.
float ticFraction = 0.; float ticFraction = 0.;
// [BB] In case the tic counter is frozen we have to leave ticFraction at zero. // [BB] In case the tic counter is frozen we have to leave ticFraction at zero.
if ( ConsoleState == c_up && menuactive != MENU_On && !(level.flags & LEVEL_FROZEN) ) if ( ConsoleState == c_up && menuactive != MENU_On && !(level.flags2 & LEVEL2_FROZEN) )
{ {
float time = GetTimeFloat(); float time = GetTimeFloat();
ticFraction = (time - static_cast<int>(time)); ticFraction = (time - static_cast<int>(time));

View file

@ -248,22 +248,22 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
y = MAX(BigFont->GetHeight() * 4, y); y = MAX(BigFont->GetHeight() * 4, y);
} }
for (i = 0; i < teams.Size (); i++) for (i = 0; i < Teams.Size (); i++)
{ {
teams[i].players = 0; Teams[i].m_iPlayerCount = 0;
teams[i].score = 0; Teams[i].m_iScore = 0;
} }
for (i = 0; i < MAXPLAYERS; ++i) for (i = 0; i < MAXPLAYERS; ++i)
{ {
if (playeringame[sortedplayers[i]-players] && TEAMINFO_IsValidTeam (sortedplayers[i]->userinfo.team)) if (playeringame[sortedplayers[i]-players] && TeamLibrary.IsValidTeam (sortedplayers[i]->userinfo.team))
{ {
if (teams[sortedplayers[i]->userinfo.team].players++ == 0) if (Teams[sortedplayers[i]->userinfo.team].m_iPlayerCount++ == 0)
{ {
numTeams++; numTeams++;
} }
teams[sortedplayers[i]->userinfo.team].score += sortedplayers[i]->fragcount; Teams[sortedplayers[i]->userinfo.team].m_iScore += sortedplayers[i]->fragcount;
} }
} }
@ -271,9 +271,9 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
int numscores = 0; int numscores = 0;
int scorex; int scorex;
for (i = 0; i < teams.Size(); ++i) for (i = 0; i < Teams.Size(); ++i)
{ {
if (teams[i].players) if (Teams[i].m_iPlayerCount)
{ {
numscores++; numscores++;
} }
@ -281,14 +281,14 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
scorex = (SCREENWIDTH - scorexwidth * (numscores - 1)) / 2; scorex = (SCREENWIDTH - scorexwidth * (numscores - 1)) / 2;
for (i = 0; i < teams.Size(); ++i) for (i = 0; i < Teams.Size(); ++i)
{ {
if (teams[i].players) if (Teams[i].m_iPlayerCount)
{ {
char score[80]; char score[80];
mysnprintf (score, countof(score), "%d", teams[i].score); mysnprintf (score, countof(score), "%d", Teams[i].m_iScore);
screen->DrawText (BigFont, teams[i].GetTextColor(), screen->DrawText (BigFont, Teams[i].GetTextColor(),
scorex - BigFont->StringWidth(score)*CleanXfac/2, y, score, scorex - BigFont->StringWidth(score)*CleanXfac/2, y, score,
DTA_CleanNoMove, true, TAG_DONE); DTA_CleanNoMove, true, TAG_DONE);
@ -400,9 +400,9 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
screen->DrawText (SmallFont, color, col4, y, player->userinfo.netname, screen->DrawText (SmallFont, color, col4, y, player->userinfo.netname,
DTA_CleanNoMove, true, TAG_DONE); DTA_CleanNoMove, true, TAG_DONE);
if (teamplay && teams[player->userinfo.team].logo.IsNotEmpty()) if (teamplay && Teams[player->userinfo.team].GetLogo ().IsNotEmpty ())
{ {
FTexture *pic = TexMan[teams[player->userinfo.team].logo]; FTexture *pic = TexMan[Teams[player->userinfo.team].GetLogo ().GetChars ()];
screen->DrawTexture (pic, col1 - (pic->GetWidth() + 2) * CleanXfac, y, screen->DrawTexture (pic, col1 - (pic->GetWidth() + 2) * CleanXfac, y,
DTA_CleanNoMove, true, TAG_DONE); DTA_CleanNoMove, true, TAG_DONE);
} }
@ -437,8 +437,8 @@ int HU_GetRowColor(player_t *player, bool highlight)
{ {
if (teamplay && deathmatch) if (teamplay && deathmatch)
{ {
if (TEAMINFO_IsValidTeam (player->userinfo.team)) if (TeamLibrary.IsValidTeam (player->userinfo.team))
return teams[player->userinfo.team].GetTextColor(); return Teams[player->userinfo.team].GetTextColor();
else else
return CR_GREY; return CR_GREY;
} }

View file

@ -236,7 +236,7 @@ void cht_DoCheat (player_t *player, int cheat)
if (i == 4) if (i == 4)
{ {
level.flags ^= LEVEL_ALLMAP; level.flags2 ^= LEVEL2_ALLMAP;
} }
else if (player->mo != NULL && player->health >= 0) else if (player->mo != NULL && player->health >= 0)
{ {

View file

@ -2164,8 +2164,8 @@ static void M_PlayerSetupDrawer ()
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT+yo, "Team", screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT+yo, "Team",
DTA_Clean, true, TAG_DONE); DTA_Clean, true, TAG_DONE);
screen->DrawText (SmallFont, value, x, PSetupDef.y + LINEHEIGHT+yo, screen->DrawText (SmallFont, value, x, PSetupDef.y + LINEHEIGHT+yo,
!TEAMINFO_IsValidTeam (players[consoleplayer].userinfo.team) ? "None" : !TeamLibrary.IsValidTeam (players[consoleplayer].userinfo.team) ? "None" :
teams[players[consoleplayer].userinfo.team].name, Teams[players[consoleplayer].userinfo.team].GetName (),
DTA_Clean, true, TAG_DONE); DTA_Clean, true, TAG_DONE);
// Draw player character // Draw player character
@ -2640,11 +2640,11 @@ static void M_ChangePlayerTeam (int choice)
{ {
if (team == 0) if (team == 0)
{ {
team = TEAM_None; team = TEAM_NONE;
} }
else if (team == TEAM_None) else if (team == TEAM_NONE)
{ {
team = teams.Size () - 1; team = Teams.Size () - 1;
} }
else else
{ {
@ -2653,11 +2653,11 @@ static void M_ChangePlayerTeam (int choice)
} }
else else
{ {
if (team == int(teams.Size () - 1)) if (team == int(Teams.Size () - 1))
{ {
team = TEAM_None; team = TEAM_NONE;
} }
else if (team == TEAM_None) else if (team == TEAM_NONE)
{ {
team = 0; team = 0;
} }

View file

@ -140,6 +140,7 @@ typedef struct menuitem_s {
int key2; int key2;
char *res2; char *res2;
void *extra; void *extra;
float discretecenter;
} c; } c;
union { union {
float step; float step;

View file

@ -437,6 +437,7 @@ menuitem_t ControlsItems[] =
{ control, "Next item", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"invnext"} }, { control, "Next item", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"invnext"} },
{ control, "Previous item", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"invprev"} }, { control, "Previous item", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"invprev"} },
{ control, "Drop item", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"invdrop"} }, { control, "Drop item", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"invdrop"} },
{ control, "Drop weapon", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"weapdrop"} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ whitetext,"Other", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { whitetext,"Other", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ control, "Toggle automap", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"togglemap"} }, { control, "Toggle automap", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"togglemap"} },
@ -1117,7 +1118,7 @@ static menu_t DMFlagsMenu =
*=======================================*/ *=======================================*/
static menuitem_t CompatibilityItems[] = { static menuitem_t CompatibilityItems[] = {
{ discrete, "Compatibility mode", {&compatmode}, {5.0}, {0.0}, {0.0}, {CompatModes} }, { discrete, "Compatibility mode", {&compatmode}, {5.0}, {1.0}, {0.0}, {CompatModes} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ bitflag, "Find shortest textures like Doom", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SHORTTEX} }, { bitflag, "Find shortest textures like Doom", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SHORTTEX} },
{ bitflag, "Use buggier stair building", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_STAIRINDEX} }, { bitflag, "Use buggier stair building", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_STAIRINDEX} },
@ -1552,7 +1553,8 @@ static void CalcIndent (menu_t *menu)
for (i = 0; i < menu->numitems; i++) for (i = 0; i < menu->numitems; i++)
{ {
item = menu->items + i; item = menu->items + i;
if (item->type != whitetext && item->type != redtext && item->type != screenres) if (item->type != whitetext && item->type != redtext && item->type != screenres &&
(item->type != discrete || !item->c.discretecenter))
{ {
thiswidth = SmallFont->StringWidth (item->label); thiswidth = SmallFont->StringWidth (item->label);
if (thiswidth > widest) if (thiswidth > widest)
@ -1682,6 +1684,7 @@ void M_OptDrawer ()
UCVarValue value; UCVarValue value;
DWORD overlay; DWORD overlay;
int labelofs; int labelofs;
int indent;
if (!CurrentMenu->DontDim) if (!CurrentMenu->DontDim)
{ {
@ -1733,6 +1736,14 @@ void M_OptDrawer ()
item = CurrentMenu->items + i; item = CurrentMenu->items + i;
overlay = 0; overlay = 0;
if (item->type == discrete && item->c.discretecenter)
{
indent = 160;
}
else
{
indent = CurrentMenu->indent;
}
if (item->type != screenres) if (item->type != screenres)
{ {
@ -1741,14 +1752,14 @@ void M_OptDrawer ()
{ {
case more: case more:
case safemore: case safemore:
x = CurrentMenu->indent - width; x = indent - width;
color = MoreColor; color = MoreColor;
break; break;
case numberedmore: case numberedmore:
case rsafemore: case rsafemore:
case rightmore: case rightmore:
x = CurrentMenu->indent + 14; x = indent + 14;
color = item->type != rightmore ? CR_GREEN : MoreColor; color = item->type != rightmore ? CR_GREEN : MoreColor;
break; break;
@ -1763,12 +1774,12 @@ void M_OptDrawer ()
break; break;
case listelement: case listelement:
x = CurrentMenu->indent + 14; x = indent + 14;
color = LabelColor; color = LabelColor;
break; break;
case colorpicker: case colorpicker:
x = CurrentMenu->indent + 14; x = indent + 14;
color = MoreColor; color = MoreColor;
break; break;
@ -1780,7 +1791,7 @@ void M_OptDrawer ()
// Intentional fall-through // Intentional fall-through
default: default:
x = CurrentMenu->indent - width; x = indent - width;
color = (item->type == control && menuactive == MENU_WaitKey && i == CurrentItem) color = (item->type == control && menuactive == MENU_WaitKey && i == CurrentItem)
? CR_YELLOW : LabelColor; ? CR_YELLOW : LabelColor;
break; break;
@ -1795,7 +1806,7 @@ void M_OptDrawer ()
char tbuf[16]; char tbuf[16];
mysnprintf (tbuf, countof(tbuf), "%d.", item->b.position); mysnprintf (tbuf, countof(tbuf), "%d.", item->b.position);
x = CurrentMenu->indent - SmallFont->StringWidth (tbuf); x = indent - SmallFont->StringWidth (tbuf);
screen->DrawText (SmallFont, CR_GREY, x, y, tbuf, DTA_Clean, true, TAG_DONE); screen->DrawText (SmallFont, CR_GREY, x, y, tbuf, DTA_Clean, true, TAG_DONE);
} }
break; break;
@ -1812,13 +1823,13 @@ void M_OptDrawer ()
if (v == vals) if (v == vals)
{ {
screen->DrawText (SmallFont, ValueColor, CurrentMenu->indent + 14, y, "Unknown", screen->DrawText (SmallFont, ValueColor, indent + 14, y, "Unknown",
DTA_Clean, true, TAG_DONE); DTA_Clean, true, TAG_DONE);
} }
else else
{ {
screen->DrawText (SmallFont, item->type == cdiscrete ? v : ValueColor, screen->DrawText (SmallFont, item->type == cdiscrete ? v : ValueColor,
CurrentMenu->indent + 14, y, item->e.values[v].name, indent + 14, y, item->e.values[v].name,
DTA_Clean, true, TAG_DONE); DTA_Clean, true, TAG_DONE);
} }
@ -1861,13 +1872,13 @@ void M_OptDrawer ()
if (v == vals) if (v == vals)
{ {
screen->DrawText (SmallFont, ValueColor, CurrentMenu->indent + 14, y, "Unknown", screen->DrawText (SmallFont, ValueColor, indent + 14, y, "Unknown",
DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE); DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE);
} }
else else
{ {
screen->DrawText (SmallFont, item->type == cdiscrete ? v : ValueColor, screen->DrawText (SmallFont, item->type == cdiscrete ? v : ValueColor,
CurrentMenu->indent + 14, y, indent + 14, y,
item->type != discretes ? item->e.values[v].name : item->e.valuestrings[v].name.GetChars(), item->type != discretes ? item->e.values[v].name : item->e.valuestrings[v].name.GetChars(),
DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE); DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE);
} }
@ -1881,7 +1892,7 @@ void M_OptDrawer ()
value = item->a.cvar->GetGenericRep (CVAR_String); value = item->a.cvar->GetGenericRep (CVAR_String);
v = M_FindCurVal(value.String, item->e.enumvalues, (int)item->b.numvalues); v = M_FindCurVal(value.String, item->e.enumvalues, (int)item->b.numvalues);
screen->DrawText(SmallFont, ValueColor, CurrentMenu->indent + 14, y, v, DTA_Clean, true, TAG_DONE); screen->DrawText(SmallFont, ValueColor, indent + 14, y, v, DTA_Clean, true, TAG_DONE);
} }
break; break;
@ -1895,11 +1906,11 @@ void M_OptDrawer ()
if (v == vals) if (v == vals)
{ {
UCVarValue val = item->a.guidcvar->GetGenericRep (CVAR_String); UCVarValue val = item->a.guidcvar->GetGenericRep (CVAR_String);
screen->DrawText (SmallFont, ValueColor, CurrentMenu->indent + 14, y, val.String, DTA_Clean, true, TAG_DONE); screen->DrawText (SmallFont, ValueColor, indent + 14, y, val.String, DTA_Clean, true, TAG_DONE);
} }
else else
{ {
screen->DrawText (SmallFont, ValueColor, CurrentMenu->indent + 14, y, item->e.guidvalues[v].Name, screen->DrawText (SmallFont, ValueColor, indent + 14, y, item->e.guidvalues[v].Name,
DTA_Clean, true, TAG_DONE); DTA_Clean, true, TAG_DONE);
} }
@ -1907,22 +1918,22 @@ void M_OptDrawer ()
break; break;
case nochoice: case nochoice:
screen->DrawText (SmallFont, CR_GOLD, CurrentMenu->indent + 14, y, screen->DrawText (SmallFont, CR_GOLD, indent + 14, y,
(item->e.values[(int)item->b.min]).name, DTA_Clean, true, TAG_DONE); (item->e.values[(int)item->b.min]).name, DTA_Clean, true, TAG_DONE);
break; break;
case slider: case slider:
value = item->a.cvar->GetGenericRep (CVAR_Float); value = item->a.cvar->GetGenericRep (CVAR_Float);
M_DrawSlider (CurrentMenu->indent + 14, y + labelofs, item->b.min, item->c.max, value.Float); M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, value.Float);
break; break;
case absslider: case absslider:
value = item->a.cvar->GetGenericRep (CVAR_Float); value = item->a.cvar->GetGenericRep (CVAR_Float);
M_DrawSlider (CurrentMenu->indent + 14, y + labelofs, item->b.min, item->c.max, fabs(value.Float)); M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, fabs(value.Float));
break; break;
case intslider: case intslider:
M_DrawSlider (CurrentMenu->indent + 14, y + labelofs, item->b.min, item->c.max, item->a.fval); M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, item->a.fval);
break; break;
case control: case control:
@ -1932,11 +1943,11 @@ void M_OptDrawer ()
C_NameKeys (description, item->b.key1, item->c.key2); C_NameKeys (description, item->b.key1, item->c.key2);
if (description[0]) if (description[0])
{ {
M_DrawConText(CR_WHITE, CurrentMenu->indent + 14, y-1+labelofs, description); M_DrawConText(CR_WHITE, indent + 14, y-1+labelofs, description);
} }
else else
{ {
screen->DrawText(SmallFont, CR_BLACK, CurrentMenu->indent + 14, y + labelofs, "---", screen->DrawText(SmallFont, CR_BLACK, indent + 14, y + labelofs, "---",
DTA_Clean, true, TAG_DONE); DTA_Clean, true, TAG_DONE);
} }
} }
@ -1945,7 +1956,7 @@ void M_OptDrawer ()
case colorpicker: case colorpicker:
{ {
int box_x, box_y; int box_x, box_y;
box_x = (CurrentMenu->indent - 35 - 160) * CleanXfac + screen->GetWidth()/2; box_x = (indent - 35 - 160) * CleanXfac + screen->GetWidth()/2;
box_y = (y - ((gameinfo.gametype & GAME_Raven) ? 99 : 100)) * CleanYfac + screen->GetHeight()/2; box_y = (y - ((gameinfo.gametype & GAME_Raven) ? 99 : 100)) * CleanYfac + screen->GetHeight()/2;
screen->Clear (box_x, box_y, box_x + 32*CleanXfac, box_y + (fontheight-1)*CleanYfac, screen->Clear (box_x, box_y, box_x + 32*CleanXfac, box_y + (fontheight-1)*CleanYfac,
item->a.colorcvar->GetIndex(), 0); item->a.colorcvar->GetIndex(), 0);
@ -1961,7 +1972,7 @@ void M_OptDrawer ()
box_y = (y - 98) * CleanYfac + screen->GetHeight()/2; box_y = (y - 98) * CleanYfac + screen->GetHeight()/2;
p = 0; p = 0;
box_x = (CurrentMenu->indent - 32 - 160) * CleanXfac + screen->GetWidth()/2; box_x = (indent - 32 - 160) * CleanXfac + screen->GetWidth()/2;
for (x1 = 0, p = int(item->b.min * 16); x1 < 16; ++p, ++x1) for (x1 = 0, p = int(item->b.min * 16); x1 < 16; ++p, ++x1)
{ {
screen->Clear (box_x, box_y, box_x + w, box_y + h, p, 0); screen->Clear (box_x, box_y, box_x + w, box_y + h, p, 0);
@ -2016,7 +2027,7 @@ void M_OptDrawer ()
} }
screen->DrawText (SmallFont, ValueColor, screen->DrawText (SmallFont, ValueColor,
CurrentMenu->indent + 14, y, str, DTA_Clean, true, TAG_DONE); indent + 14, y, str, DTA_Clean, true, TAG_DONE);
} }
break; break;
@ -2028,7 +2039,7 @@ void M_OptDrawer ()
i == CurrentItem && i == CurrentItem &&
(skullAnimCounter < 6 || menuactive == MENU_WaitKey)) (skullAnimCounter < 6 || menuactive == MENU_WaitKey))
{ {
M_DrawConText(CR_RED, CurrentMenu->indent + 3, y-1+labelofs, "\xd"); M_DrawConText(CR_RED, indent + 3, y-1+labelofs, "\xd");
} }
} }
else else

View file

@ -1,10 +1,11 @@
/* /*
This file is based on fmopl.c from MAME 0.95. The non-YM3816 parts have been This file is based on fmopl.c from MAME 0.95. The non-YM3816 parts have been
ripped out in the interest of trying to make this a bit faster, since Doom ripped out in the interest of making this simpler, since Doom music doesn't
music doesn't need them. I also made it render the sound a voice at a time need them. I also made it render the sound a voice at a time instead of a
instead of a sample at a time, so unused voices don't waste time being sample at a time, so unused voices don't waste time being calculated. If all
calculated. voices are playing, it's not much difference, but it does offer a big
improvement when only a few voices are playing.
Here is the appropriate section from mame.txt: Here is the appropriate section from mame.txt:
@ -1919,41 +1920,32 @@ void YM3812UpdateOne(void *chip, float *buffer, int length)
UINT32 eg_timer_bak = OPL->eg_timer; UINT32 eg_timer_bak = OPL->eg_timer;
UINT32 eg_cnt_bak = OPL->eg_cnt; UINT32 eg_cnt_bak = OPL->eg_cnt;
UINT32 noise_p_bak = OPL->noise_p;
UINT32 noise_rng_bak = OPL->noise_rng;
UINT32 lfo_am_cnt_out = lfo_am_cnt_bak; UINT32 lfo_am_cnt_out = lfo_am_cnt_bak;
UINT32 eg_timer_out = eg_timer_bak; UINT32 eg_timer_out = eg_timer_bak;
UINT32 eg_cnt_out = eg_cnt_bak; UINT32 eg_cnt_out = eg_cnt_bak;
UINT32 noise_p_out = noise_p_bak;
UINT32 noise_rng_out = noise_rng_bak;
for (i = 0; i <= (rhythm ? 5 : 8); ++i) for (i = 0; i <= (rhythm ? 5 : 8); ++i)
{ {
OPL->lfo_am_cnt = lfo_am_cnt_bak; OPL->lfo_am_cnt = lfo_am_cnt_bak;
OPL->eg_timer = eg_timer_bak; OPL->eg_timer = eg_timer_bak;
OPL->eg_cnt = eg_cnt_bak; OPL->eg_cnt = eg_cnt_bak;
OPL->noise_p = noise_p_bak;
OPL->noise_rng = noise_rng_bak;
if (CalcVoice (OPL, i, buffer, length)) if (CalcVoice (OPL, i, buffer, length))
{ {
lfo_am_cnt_out = OPL->lfo_am_cnt; lfo_am_cnt_out = OPL->lfo_am_cnt;
eg_timer_out = OPL->eg_timer; eg_timer_out = OPL->eg_timer;
eg_cnt_out = OPL->eg_cnt; eg_cnt_out = OPL->eg_cnt;
noise_p_out = OPL->noise_p;
noise_rng_out = OPL->noise_rng;
} }
} }
OPL->lfo_am_cnt = lfo_am_cnt_out; OPL->lfo_am_cnt = lfo_am_cnt_out;
OPL->eg_timer = eg_timer_out; OPL->eg_timer = eg_timer_out;
OPL->eg_cnt = eg_cnt_out; OPL->eg_cnt = eg_cnt_out;
OPL->noise_p = noise_p_out;
OPL->noise_rng = noise_rng_out;
if (rhythm) /* Rhythm part */ if (rhythm) /* Rhythm part */
{ {
OPL->lfo_am_cnt = lfo_am_cnt_bak;
OPL->eg_timer = eg_timer_bak;
OPL->eg_cnt = eg_cnt_bak;
CalcRhythm (OPL, buffer, length); CalcRhythm (OPL, buffer, length);
} }
} }
@ -1979,7 +1971,6 @@ static bool CalcVoice (FM_OPL *OPL, int voice, float *buffer, int length)
OPL_CALC_CH(CH, buffer + i); OPL_CALC_CH(CH, buffer + i);
advance(OPL, voice, voice); advance(OPL, voice, voice);
advance_noise(OPL);
} }
return true; return true;
} }

View file

@ -69,6 +69,7 @@
#include "r_translate.h" #include "r_translate.h"
#include "sbarinfo.h" #include "sbarinfo.h"
#include "cmdlib.h" #include "cmdlib.h"
#include "m_png.h"
extern FILE *Logfile; extern FILE *Logfile;
@ -118,6 +119,222 @@ struct FBehavior::ArrayInfo
TArray<FBehavior *> FBehavior::StaticModules; TArray<FBehavior *> FBehavior::StaticModules;
//============================================================================
//
// Global and world variables
//
//============================================================================
// ACS variables with world scope
SDWORD ACS_WorldVars[NUM_WORLDVARS];
FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
// ACS variables with global scope
SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
//============================================================================
//
//
//
//============================================================================
void P_ClearACSVars(bool alsoglobal)
{
int i;
memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars));
for (i = 0; i < NUM_WORLDVARS; ++i)
{
ACS_WorldArrays[i].Clear ();
}
if (alsoglobal)
{
memset (ACS_GlobalVars, 0, sizeof(ACS_GlobalVars));
for (i = 0; i < NUM_GLOBALVARS; ++i)
{
ACS_GlobalArrays[i].Clear ();
}
}
}
//============================================================================
//
//
//
//============================================================================
static void WriteVars (FILE *file, SDWORD *vars, size_t count, DWORD id)
{
size_t i, j;
for (i = 0; i < count; ++i)
{
if (vars[i] != 0)
break;
}
if (i < count)
{
// Find last non-zero var. Anything beyond the last stored variable
// will be zeroed at load time.
for (j = count-1; j > i; --j)
{
if (vars[j] != 0)
break;
}
FPNGChunkArchive arc (file, id);
for (i = 0; i <= j; ++i)
{
DWORD var = vars[i];
arc << var;
}
}
}
//============================================================================
//
//
//
//============================================================================
static void ReadVars (PNGHandle *png, SDWORD *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
size_t used = 0;
if (len != 0)
{
DWORD var;
size_t i;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
used = len / 4;
for (i = 0; i < used; ++i)
{
arc << var;
vars[i] = var;
}
png->File->ResetFilePtr();
}
if (used < count)
{
memset (&vars[used], 0, (count-used)*4);
}
}
//============================================================================
//
//
//
//============================================================================
static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int count, DWORD id)
{
unsigned int i, j;
// Find the first non-empty array.
for (i = 0; i < count; ++i)
{
if (vars[i].CountUsed() != 0)
break;
}
if (i < count)
{
// Find last non-empty array. Anything beyond the last stored array
// will be emptied at load time.
for (j = count-1; j > i; --j)
{
if (vars[j].CountUsed() != 0)
break;
}
FPNGChunkArchive arc (file, id);
arc.WriteCount (i);
arc.WriteCount (j);
for (; i <= j; ++i)
{
arc.WriteCount (vars[i].CountUsed());
FWorldGlobalArray::ConstIterator it(vars[i]);
const FWorldGlobalArray::Pair *pair;
while (it.NextPair (pair))
{
arc.WriteCount (pair->Key);
arc.WriteCount (pair->Value);
}
}
}
}
//============================================================================
//
//
//
//============================================================================
static void ReadArrayVars (PNGHandle *png, FWorldGlobalArray *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
unsigned int i, k;
for (i = 0; i < count; ++i)
{
vars[i].Clear ();
}
if (len != 0)
{
DWORD max, size;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
i = arc.ReadCount ();
max = arc.ReadCount ();
for (; i <= max; ++i)
{
size = arc.ReadCount ();
for (k = 0; k < size; ++k)
{
SDWORD key, val;
key = arc.ReadCount();
val = arc.ReadCount();
vars[i].Insert (key, val);
}
}
png->File->ResetFilePtr();
}
}
//============================================================================
//
//
//
//============================================================================
void P_ReadACSVars(PNGHandle *png)
{
ReadVars (png, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));
ReadVars (png, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
ReadArrayVars (png, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
ReadArrayVars (png, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
}
//============================================================================
//
//
//
//============================================================================
void P_WriteACSVars(FILE *stdfile)
{
WriteVars (stdfile, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));
WriteVars (stdfile, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
WriteArrayVars (stdfile, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
WriteArrayVars (stdfile, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
}
//---- Inventory functions --------------------------------------// //---- Inventory functions --------------------------------------//
// //
@ -2157,24 +2374,28 @@ void DLevelScript::DoSetFont (int fontnum)
} }
} }
#define APROP_Health 0 enum
#define APROP_Speed 1 {
#define APROP_Damage 2 APROP_Health = 0,
#define APROP_Alpha 3 APROP_Speed = 1,
#define APROP_RenderStyle 4 APROP_Damage = 2,
#define APROP_Ambush 10 APROP_Alpha = 3,
#define APROP_Invulnerable 11 APROP_RenderStyle = 4,
#define APROP_JumpZ 12 // [GRB] APROP_SeeSound = 5, // Sounds can only be set, not gotten
#define APROP_ChaseGoal 13 APROP_AttackSound = 6,
#define APROP_Frightened 14 APROP_PainSound = 7,
#define APROP_Gravity 15 APROP_DeathSound = 8,
#define APROP_Friendly 16 APROP_ActiveSound = 9,
#define APROP_SpawnHealth 17 APROP_Ambush = 10,
#define APROP_SeeSound 5 // Sounds can only be set, not gotten APROP_Invulnerable = 11,
#define APROP_AttackSound 6 APROP_JumpZ = 12, // [GRB]
#define APROP_PainSound 7 APROP_ChaseGoal = 13,
#define APROP_DeathSound 8 APROP_Frightened = 14,
#define APROP_ActiveSound 9 APROP_Gravity = 15,
APROP_Friendly = 16,
APROP_SpawnHealth = 17,
APROP_Dropped = 18,
};
// These are needed for ACS's APROP_RenderStyle // These are needed for ACS's APROP_RenderStyle
static const int LegacyRenderStyleIndices[] = static const int LegacyRenderStyleIndices[] =
@ -2253,6 +2474,10 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
if (value) actor->flags |= MF_AMBUSH; else actor->flags &= ~MF_AMBUSH; if (value) actor->flags |= MF_AMBUSH; else actor->flags &= ~MF_AMBUSH;
break; break;
case APROP_Dropped:
if (value) actor->flags |= MF_DROPPED; else actor->flags &= ~MF_DROPPED;
break;
case APROP_Invulnerable: case APROP_Invulnerable:
if (value) actor->flags2 |= MF2_INVULNERABLE; else actor->flags2 &= ~MF2_INVULNERABLE; if (value) actor->flags2 |= MF2_INVULNERABLE; else actor->flags2 &= ~MF2_INVULNERABLE;
break; break;
@ -2356,6 +2581,7 @@ int DLevelScript::GetActorProperty (int tid, int property)
return STYLE_Normal; return STYLE_Normal;
case APROP_Gravity: return actor->gravity; case APROP_Gravity: return actor->gravity;
case APROP_Ambush: return !!(actor->flags & MF_AMBUSH); case APROP_Ambush: return !!(actor->flags & MF_AMBUSH);
case APROP_Dropped: return !!(actor->flags & MF_DROPPED);
case APROP_ChaseGoal: return !!(actor->flags5 & MF5_CHASEGOAL); case APROP_ChaseGoal: return !!(actor->flags5 & MF5_CHASEGOAL);
case APROP_Frightened: return !!(actor->flags4 & MF4_FRIGHTENED); case APROP_Frightened: return !!(actor->flags4 & MF4_FRIGHTENED);
case APROP_Friendly: return !!(actor->flags & MF_FRIENDLY); case APROP_Friendly: return !!(actor->flags & MF_FRIENDLY);

View file

@ -36,6 +36,7 @@
#define __P_ACS_H__ #define __P_ACS_H__
#include "dobject.h" #include "dobject.h"
#include "dthinker.h"
#include "doomtype.h" #include "doomtype.h"
#define LOCAL_SIZE 20 #define LOCAL_SIZE 20
@ -44,6 +45,34 @@
class FFont; class FFont;
class FileReader; class FileReader;
enum
{
NUM_WORLDVARS = 256,
NUM_GLOBALVARS = 64
};
struct InitIntToZero
{
void Init(int &v)
{
v = 0;
}
};
typedef TMap<SDWORD, SDWORD, THashTraits<SDWORD>, InitIntToZero> FWorldGlobalArray;
// ACS variables with world scope
extern SDWORD ACS_WorldVars[NUM_WORLDVARS];
extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
// ACS variables with global scope
extern SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
void P_ReadACSVars(PNGHandle *);
void P_WriteACSVars(FILE*);
void P_ClearACSVars(bool);
// The in-memory version // The in-memory version
struct ScriptPtr struct ScriptPtr
{ {

View file

@ -848,7 +848,7 @@ static void DrawConversationMenu ()
} }
// [CW] Freeze the game depending on MAPINFO options. // [CW] Freeze the game depending on MAPINFO options.
if (ConversationPauseTic < gametic && !multiplayer && !(level.flags & LEVEL_CONV_SINGLE_UNFREEZE)) if (ConversationPauseTic < gametic && !multiplayer && !(level.flags2 & LEVEL2_CONV_SINGLE_UNFREEZE))
{ {
menuactive = MENU_On; menuactive = MENU_On;
} }

View file

@ -1590,10 +1590,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look)
// Let the self wander around aimlessly looking for a fight // Let the self wander around aimlessly looking for a fight
if (self->SeeState != NULL) if (self->SeeState != NULL)
{ {
if (!(self->flags & MF_INCHASE)) self->SetState (self->SeeState);
{
self->SetState (self->SeeState);
}
} }
else else
{ {
@ -1638,7 +1635,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look)
} }
} }
if (self->target && !(self->flags & MF_INCHASE)) if (self->target)
{ {
self->SetState (self->SeeState); self->SetState (self->SeeState);
} }
@ -1757,6 +1754,10 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
{ {
int delta; int delta;
if (actor->flags & MF_INCHASE)
{
return;
}
actor->flags |= MF_INCHASE; actor->flags |= MF_INCHASE;
// [RH] Andy Baker's stealth monsters // [RH] Andy Baker's stealth monsters
@ -2183,7 +2184,6 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
S_Sound (corpsehit, CHAN_BODY, "vile/raise", 1, ATTN_IDLE); S_Sound (corpsehit, CHAN_BODY, "vile/raise", 1, ATTN_IDLE);
info = corpsehit->GetDefault (); info = corpsehit->GetDefault ();
corpsehit->SetState (raisestate);
corpsehit->height = info->height; // [RH] Use real mobj height corpsehit->height = info->height; // [RH] Use real mobj height
corpsehit->radius = info->radius; // [RH] Use real radius corpsehit->radius = info->radius; // [RH] Use real radius
/* /*
@ -2207,6 +2207,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
// You are the Archvile's minion now, so hate what it hates // You are the Archvile's minion now, so hate what it hates
corpsehit->CopyFriendliness (self, false); corpsehit->CopyFriendliness (self, false);
corpsehit->SetState (raisestate);
return true; return true;
} }
@ -2652,9 +2653,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BossDeath)
// Do generic special death actions first // Do generic special death actions first
bool checked = false; bool checked = false;
FSpecialAction *sa = level.info->specialactions; for(unsigned i=0; i<level.info->specialactions.Size(); i++)
while (sa)
{ {
FSpecialAction *sa = &level.info->specialactions[i];
if (type == sa->Type || mytype == sa->Type) if (type == sa->Type || mytype == sa->Type)
{ {
if (!checked && !CheckBossDeath(self)) if (!checked && !CheckBossDeath(self))
@ -2666,7 +2668,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_BossDeath)
LineSpecials[sa->Action](NULL, self, false, LineSpecials[sa->Action](NULL, self, false,
sa->Args[0], sa->Args[1], sa->Args[2], sa->Args[3], sa->Args[4]); sa->Args[0], sa->Args[1], sa->Args[2], sa->Args[3], sa->Args[4]);
} }
sa = sa->Next;
} }
// [RH] These all depend on the presence of level flags now // [RH] These all depend on the presence of level flags now

View file

@ -957,6 +957,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
if (df != NULL) if (df != NULL)
{ {
fixed_t * pdf = df->CheckKey(mod); fixed_t * pdf = df->CheckKey(mod);
if (pdf== NULL && mod != NAME_None) pdf = df->CheckKey(NAME_None);
if (pdf != NULL) if (pdf != NULL)
{ {
damage = FixedMul(damage, *pdf); damage = FixedMul(damage, *pdf);
@ -1295,8 +1296,8 @@ bool AActor::OkayToSwitchTarget (AActor *other)
int infight; int infight;
if (flags5 & MF5_NOINFIGHTING) infight=-1; if (flags5 & MF5_NOINFIGHTING) infight=-1;
else if (level.flags & LEVEL_TOTALINFIGHTING) infight=1; else if (level.flags2 & LEVEL2_TOTALINFIGHTING) infight=1;
else if (level.flags & LEVEL_NOINFIGHTING) infight=-1; else if (level.flags2 & LEVEL2_NOINFIGHTING) infight=-1;
else infight = infighting; else infight = infighting;
if (infight < 0 && other->player == NULL && !IsHostile (other)) if (infight < 0 && other->player == NULL && !IsHostile (other))

View file

@ -2489,7 +2489,7 @@ FUNC(LS_SetPlayerProperty)
} }
else if (it->player - players == consoleplayer) else if (it->player - players == consoleplayer)
{ {
level.flags |= LEVEL_ALLMAP; level.flags2 |= LEVEL2_ALLMAP;
} }
} }
else else
@ -2504,7 +2504,7 @@ FUNC(LS_SetPlayerProperty)
} }
else if (it->player - players == consoleplayer) else if (it->player - players == consoleplayer)
{ {
level.flags &= ~LEVEL_ALLMAP; level.flags2 &= ~LEVEL2_ALLMAP;
} }
} }
} }
@ -2525,7 +2525,7 @@ FUNC(LS_SetPlayerProperty)
} }
else if (i == consoleplayer) else if (i == consoleplayer)
{ {
level.flags |= LEVEL_ALLMAP; level.flags2 |= LEVEL2_ALLMAP;
} }
} }
else else
@ -2540,7 +2540,7 @@ FUNC(LS_SetPlayerProperty)
} }
else if (i == consoleplayer) else if (i == consoleplayer)
{ {
level.flags &= ~LEVEL_ALLMAP; level.flags2 &= ~LEVEL2_ALLMAP;
} }
} }
} }

View file

@ -672,7 +672,7 @@ bool PIT_CheckLine (line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
// better than Strife's handling of rails, which lets you jump into rails // better than Strife's handling of rails, which lets you jump into rails
// from either side. How long until somebody reports this as a bug and I'm // from either side. How long until somebody reports this as a bug and I'm
// forced to say, "It's not a bug. It's a feature?" Ugh. // forced to say, "It's not a bug. It's a feature?" Ugh.
(!(level.flags & LEVEL_RAILINGHACK) || (!(level.flags2 & LEVEL2_RAILINGHACK) ||
open.bottom == tm.thing->Sector->floorplane.ZatPoint (sx, sy))) open.bottom == tm.thing->Sector->floorplane.ZatPoint (sx, sy)))
{ {
open.bottom += 32*FRACUNIT; open.bottom += 32*FRACUNIT;
@ -870,8 +870,8 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
if (!thing->player && !tm.thing->target->player) if (!thing->player && !tm.thing->target->player)
{ {
int infight; int infight;
if (level.flags & LEVEL_TOTALINFIGHTING) infight=1; if (level.flags2 & LEVEL2_TOTALINFIGHTING) infight=1;
else if (level.flags & LEVEL_NOINFIGHTING) infight=-1; else if (level.flags2 & LEVEL2_NOINFIGHTING) infight=-1;
else infight = infighting; else infight = infighting;
if (infight < 0) if (infight < 0)
@ -1412,7 +1412,7 @@ static void CheckForPushSpecial (line_t *line, int side, AActor *mobj)
} }
else if (mobj->flags2 & MF2_IMPACT) else if (mobj->flags2 & MF2_IMPACT)
{ {
if ((level.flags & LEVEL_MISSILESACTIVATEIMPACT) || if ((level.flags2 & LEVEL2_MISSILESACTIVATEIMPACT) ||
!(mobj->flags & MF_MISSILE) || !(mobj->flags & MF_MISSILE) ||
(mobj->target == NULL)) (mobj->target == NULL))
{ {

View file

@ -1831,7 +1831,7 @@ void P_MonsterFallingDamage (AActor *mo)
int damage; int damage;
int mom; int mom;
if (!(level.flags&LEVEL_MONSTERFALLINGDAMAGE)) if (!(level.flags2 & LEVEL2_MONSTERFALLINGDAMAGE))
return; return;
if (mo->floorsector->Flags & SECF_NOFALLINGDAMAGE) if (mo->floorsector->Flags & SECF_NOFALLINGDAMAGE)
return; return;
@ -2536,7 +2536,7 @@ void AActor::Tick ()
if (!(flags5 & MF5_NOTIMEFREEZE)) if (!(flags5 & MF5_NOTIMEFREEZE))
{ {
//Added by MC: Freeze mode. //Added by MC: Freeze mode.
if (bglobal.freeze || level.flags & LEVEL_FROZEN) if (bglobal.freeze || level.flags2 & LEVEL2_FROZEN)
{ {
return; return;
} }
@ -2575,7 +2575,7 @@ void AActor::Tick ()
} }
// Apply freeze mode. // Apply freeze mode.
if (( level.flags & LEVEL_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE ))) if (( level.flags2 & LEVEL2_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE )))
{ {
return; return;
} }
@ -3713,7 +3713,7 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer)
{ // Give all cards in death match mode. { // Give all cards in death match mode.
p->mo->GiveDeathmatchInventory (); p->mo->GiveDeathmatchInventory ();
} }
else if ((multiplayer || (level.flags & LEVEL_ALLOWRESPAWN)) && state == PST_REBORN && oldactor != NULL) else if ((multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN)) && state == PST_REBORN && oldactor != NULL)
{ // Special inventory handling for respawning in coop { // Special inventory handling for respawning in coop
p->mo->FilterCoopRespawnInventory (oldactor); p->mo->FilterCoopRespawnInventory (oldactor);
} }
@ -4023,7 +4023,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
} }
// don't spawn any monsters if -nomonsters // don't spawn any monsters if -nomonsters
if (((level.flags & LEVEL_NOMONSTERS) || (dmflags & DF_NO_MONSTERS)) && info->flags3 & MF3_ISMONSTER ) if (((level.flags2 & LEVEL2_NOMONSTERS) || (dmflags & DF_NO_MONSTERS)) && info->flags3 & MF3_ISMONSTER )
{ {
return NULL; return NULL;
} }
@ -4926,7 +4926,7 @@ bool AActor::IsTeammate (AActor *other)
return false; return false;
if (!deathmatch) if (!deathmatch)
return true; return true;
if (teamplay && other->player->userinfo.team != TEAM_None && if (teamplay && other->player->userinfo.team != TEAM_NONE &&
player->userinfo.team == other->player->userinfo.team) player->userinfo.team == other->player->userinfo.team)
{ {
return true; return true;

View file

@ -467,7 +467,7 @@ void P_SerializeSounds (FArchive &arc)
{ {
if (!S_ChangeMusic (name, order)) if (!S_ChangeMusic (name, order))
if (level.cdtrack == 0 || !S_ChangeCDMusic (level.cdtrack, level.cdid)) if (level.cdtrack == 0 || !S_ChangeCDMusic (level.cdtrack, level.cdid))
S_ChangeMusic (level.music, level.musicorder); S_ChangeMusic (level.Music, level.musicorder);
} }
delete[] name; delete[] name;
} }

View file

@ -1602,7 +1602,7 @@ void P_SetLineID (line_t *ld)
switch (ld->special) switch (ld->special)
{ {
case Line_SetIdentification: case Line_SetIdentification:
if (!(level.flags & LEVEL_HEXENHACK)) if (!(level.flags2 & LEVEL2_HEXENHACK))
{ {
ld->id = ld->args[0] + 256 * ld->args[4]; ld->id = ld->args[0] + 256 * ld->args[4];
ld->flags |= ld->args[1]<<16; ld->flags |= ld->args[1]<<16;
@ -1813,9 +1813,9 @@ void P_LoadLineDefs (MapData * map)
P_AdjustLine (ld); P_AdjustLine (ld);
P_SaveLineSpecial (ld); P_SaveLineSpecial (ld);
if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
if (level.flags & LEVEL_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE; if (level.flags2 & LEVEL2_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE;
} }
delete[] mldf; delete[] mldf;
} }
@ -1891,9 +1891,9 @@ void P_LoadLineDefs2 (MapData * map)
P_AdjustLine (ld); P_AdjustLine (ld);
P_SetLineID(ld); P_SetLineID(ld);
P_SaveLineSpecial (ld); P_SaveLineSpecial (ld);
if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
if (level.flags & LEVEL_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE; if (level.flags2 & LEVEL2_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE;
// convert the activation type // convert the activation type
ld->activation = 1 << GET_SPAC(ld->flags); ld->activation = 1 << GET_SPAC(ld->flags);
@ -3354,7 +3354,7 @@ void P_SetupLevel (char *lumpname, int position)
{ {
// We need translators only for Doom format maps. // We need translators only for Doom format maps.
// If none has been defined in a map use the game's default. // If none has been defined in a map use the game's default.
P_LoadTranslator(level.info->translator != NULL? (const char *)level.info->translator : gameinfo.translator); P_LoadTranslator(!level.info->Translator.IsEmpty()? level.info->Translator.GetChars() : gameinfo.translator);
} }
T_LoadScripts(map); T_LoadScripts(map);
@ -3362,9 +3362,9 @@ void P_SetupLevel (char *lumpname, int position)
{ {
// Doom format and UDMF text maps get strict monster activation unless the mapinfo // Doom format and UDMF text maps get strict monster activation unless the mapinfo
// specifies differently. // specifies differently.
if (!(level.flags & LEVEL_LAXACTIVATIONMAPINFO)) if (!(level.flags2 & LEVEL2_LAXACTIVATIONMAPINFO))
{ {
level.flags &= ~LEVEL_LAXMONSTERACTIVATION; level.flags2 &= ~LEVEL2_LAXMONSTERACTIVATION;
} }
} }
@ -3373,9 +3373,9 @@ void P_SetupLevel (char *lumpname, int position)
// set compatibility flags // set compatibility flags
if (gameinfo.gametype == GAME_Strife) if (gameinfo.gametype == GAME_Strife)
{ {
level.flags |= LEVEL_RAILINGHACK; level.flags2 |= LEVEL2_RAILINGHACK;
} }
level.flags |= LEVEL_DUMMYSWITCHES; level.flags2 |= LEVEL2_DUMMYSWITCHES;
} }
FBehavior::StaticLoadDefaultModules (); FBehavior::StaticLoadDefaultModules ();

View file

@ -239,7 +239,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType)
} }
// some old WADs use this method to create walls that change the texture when shot. // some old WADs use this method to create walls that change the texture when shot.
else if (activationType == SPAC_Impact && // only for shootable triggers else if (activationType == SPAC_Impact && // only for shootable triggers
(level.flags & LEVEL_DUMMYSWITCHES) && // this is only a compatibility setting for an old hack! (level.flags2 & LEVEL2_DUMMYSWITCHES) && // this is only a compatibility setting for an old hack!
!repeat && // only non-repeatable triggers !repeat && // only non-repeatable triggers
(special<Generic_Floor || special>Generic_Crusher) && // not for Boom's generalized linedefs (special<Generic_Floor || special>Generic_Crusher) && // not for Boom's generalized linedefs
special && // not for lines without a special special && // not for lines without a special
@ -322,7 +322,7 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType)
// lax activation checks, monsters can also activate certain lines // lax activation checks, monsters can also activate certain lines
// even without them being marked as monster activate-able. This is // even without them being marked as monster activate-able. This is
// the default for non-Hexen maps in Hexen format. // the default for non-Hexen maps in Hexen format.
if (!(level.flags & LEVEL_LAXMONSTERACTIVATION)) if (!(level.flags2 & LEVEL2_LAXMONSTERACTIVATION))
{ {
return false; return false;
} }

View file

@ -928,7 +928,7 @@ void DumpStateHelper(FStateLabels *StateList, const FString &prefix)
else else
{ {
Printf(PRINT_LOG, "%s%s: %s.%d\n", prefix.GetChars(), StateList->Labels[i].Label.GetChars(), Printf(PRINT_LOG, "%s%s: %s.%d\n", prefix.GetChars(), StateList->Labels[i].Label.GetChars(),
owner->TypeName.GetChars(), StateList->Labels[i].State - owner->ActorInfo->OwnedStates); owner->TypeName.GetChars(), int(StateList->Labels[i].State - owner->ActorInfo->OwnedStates));
} }
} }
if (StateList->Labels[i].Children != NULL) if (StateList->Labels[i].Children != NULL)

View file

@ -68,7 +68,7 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog,
kind = kind->ActorInfo->GetReplacement()->Class; kind = kind->ActorInfo->GetReplacement()->Class;
if ((GetDefaultByType (kind)->flags3 & MF3_ISMONSTER) && if ((GetDefaultByType (kind)->flags3 & MF3_ISMONSTER) &&
((dmflags & DF_NO_MONSTERS) || (level.flags & LEVEL_NOMONSTERS))) ((dmflags & DF_NO_MONSTERS) || (level.flags2 & LEVEL2_NOMONSTERS)))
return false; return false;
if (tid == 0) if (tid == 0)
@ -204,7 +204,7 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam
defflags3 = GetDefaultByType (kind)->flags3; defflags3 = GetDefaultByType (kind)->flags3;
if ((defflags3 & MF3_ISMONSTER) && if ((defflags3 & MF3_ISMONSTER) &&
((dmflags & DF_NO_MONSTERS) || (level.flags & LEVEL_NOMONSTERS))) ((dmflags & DF_NO_MONSTERS) || (level.flags2 & LEVEL2_NOMONSTERS)))
return false; return false;
if (tid == 0) if (tid == 0)

View file

@ -57,7 +57,7 @@ bool P_CheckTickerPaused ()
&& players[consoleplayer].viewz != 1 && players[consoleplayer].viewz != 1
&& wipegamestate == gamestate) && wipegamestate == gamestate)
{ {
S_PauseSound (!(level.flags & LEVEL_PAUSE_MUSIC_IN_MENUS)); S_PauseSound (!(level.flags2 & LEVEL2_PAUSE_MUSIC_IN_MENUS));
return true; return true;
} }
return false; return false;
@ -111,7 +111,7 @@ void P_Ticker (void)
// Since things will be moving, it's okay to interpolate them in the renderer. // Since things will be moving, it's okay to interpolate them in the renderer.
r_NoInterpolate = false; r_NoInterpolate = false;
if (!bglobal.freeze && !(level.flags & LEVEL_FROZEN)) if (!bglobal.freeze && !(level.flags2 & LEVEL2_FROZEN))
{ {
P_ThinkParticles (); // [RH] make the particles think P_ThinkParticles (); // [RH] make the particles think
} }
@ -126,7 +126,7 @@ void P_Ticker (void)
DThinker::RunThinkers (); DThinker::RunThinkers ();
//if added by MC: Freeze mode. //if added by MC: Freeze mode.
if (!bglobal.freeze && !(level.flags & LEVEL_FROZEN)) if (!bglobal.freeze && !(level.flags2 & LEVEL2_FROZEN))
{ {
P_UpdateSpecials (); P_UpdateSpecials ();
P_RunEffects (); // [RH] Run particle effects P_RunEffects (); // [RH] Run particle effects

View file

@ -419,9 +419,9 @@ struct UDMFParser
ld->Alpha = FRACUNIT; ld->Alpha = FRACUNIT;
ld->id = -1; ld->id = -1;
ld->sidenum[0] = ld->sidenum[1] = NO_SIDE; ld->sidenum[0] = ld->sidenum[1] = NO_SIDE;
if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
if (level.flags & LEVEL_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE; if (level.flags2 & LEVEL2_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE;
sc.MustGetToken('{'); sc.MustGetToken('{');
while (!sc.CheckToken('}')) while (!sc.CheckToken('}'))
@ -1124,19 +1124,19 @@ struct UDMFParser
case NAME_Doom: case NAME_Doom:
namespace_bits = Dm; namespace_bits = Dm;
P_LoadTranslator("xlat/doom_base.txt"); P_LoadTranslator("xlat/doom_base.txt");
level.flags |= LEVEL_DUMMYSWITCHES; level.flags2 |= LEVEL2_DUMMYSWITCHES;
floordrop = true; floordrop = true;
break; break;
case NAME_Heretic: case NAME_Heretic:
namespace_bits = Ht; namespace_bits = Ht;
P_LoadTranslator("xlat/heretic_base.txt"); P_LoadTranslator("xlat/heretic_base.txt");
level.flags |= LEVEL_DUMMYSWITCHES; level.flags2 |= LEVEL2_DUMMYSWITCHES;
floordrop = true; floordrop = true;
break; break;
case NAME_Strife: case NAME_Strife:
namespace_bits = St; namespace_bits = St;
P_LoadTranslator("xlat/strife_base.txt"); P_LoadTranslator("xlat/strife_base.txt");
level.flags |= LEVEL_DUMMYSWITCHES|LEVEL_RAILINGHACK; level.flags2 |= LEVEL2_DUMMYSWITCHES|LEVEL2_RAILINGHACK;
floordrop = true; floordrop = true;
break; break;
default: default:

View file

@ -1148,7 +1148,7 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor)
} }
} }
} }
if (!multiplayer && (level.flags & LEVEL_DEATHSLIDESHOW)) if (!multiplayer && (level.flags2 & LEVEL2_DEATHSLIDESHOW))
{ {
F_StartSlideshow (); F_StartSlideshow ();
} }
@ -1876,7 +1876,7 @@ void P_DeathThink (player_t *player)
if (level.time >= player->respawn_time || ((player->cmd.ucmd.buttons & BT_USE) && !player->isbot)) if (level.time >= player->respawn_time || ((player->cmd.ucmd.buttons & BT_USE) && !player->isbot))
{ {
player->cls = NULL; // Force a new class if the player is using a random class player->cls = NULL; // Force a new class if the player is using a random class
player->playerstate = (multiplayer || (level.flags & LEVEL_ALLOWRESPAWN)) ? PST_REBORN : PST_ENTER; player->playerstate = (multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN)) ? PST_REBORN : PST_ENTER;
if (player->mo->special1 > 2) if (player->mo->special1 > 2)
{ {
player->mo->special1 = 0; player->mo->special1 = 0;

View file

@ -1441,7 +1441,7 @@ int side_t::GetLightLevel (bool foggy, int baselight) const
{ {
if (!(Flags & WALLF_NOFAKECONTRAST)) if (!(Flags & WALLF_NOFAKECONTRAST))
{ {
if (((level.flags & LEVEL_SMOOTHLIGHTING) || (Flags & WALLF_SMOOTHLIGHTING) || r_smoothlighting) && if (((level.flags2 & LEVEL2_SMOOTHLIGHTING) || (Flags & WALLF_SMOOTHLIGHTING) || r_smoothlighting) &&
lines[linenum].dx != 0) lines[linenum].dx != 0)
{ {
baselight += int // OMG LEE KILLOUGH LIVES! :/ baselight += int // OMG LEE KILLOUGH LIVES! :/

View file

@ -1071,9 +1071,9 @@ static void S_AddSNDINFO (int lump)
mysnprintf (temp, countof(temp), "MAP%02d", sc.Number); mysnprintf (temp, countof(temp), "MAP%02d", sc.Number);
info = FindLevelInfo (temp); info = FindLevelInfo (temp);
sc.MustGetString (); sc.MustGetString ();
if (info->mapname[0] && (!(info->flags & LEVEL_MUSICDEFINED))) if (info->mapname[0] && (!(info->flags2 & LEVEL2_MUSICDEFINED)))
{ {
ReplaceString (&info->music, sc.String); info->Music = sc.String;
} }
} }
break; break;

View file

@ -163,7 +163,8 @@ void S_NoiseDebug (void)
screen->DrawText (SmallFont, CR_GOLD, 220, y, "vol", TAG_DONE); screen->DrawText (SmallFont, CR_GOLD, 220, y, "vol", TAG_DONE);
screen->DrawText (SmallFont, CR_GOLD, 260, y, "dist", TAG_DONE); screen->DrawText (SmallFont, CR_GOLD, 260, y, "dist", TAG_DONE);
screen->DrawText (SmallFont, CR_GOLD, 300, y, "chan", TAG_DONE); screen->DrawText (SmallFont, CR_GOLD, 300, y, "chan", TAG_DONE);
screen->DrawText (SmallFont, CR_GOLD, 340, y, "flags", TAG_DONE); screen->DrawText (SmallFont, CR_GOLD, 340, y, "pri", TAG_DONE);
screen->DrawText (SmallFont, CR_GOLD, 380, y, "flags", TAG_DONE);
y += 8; y += 8;
if (Channels == NULL) if (Channels == NULL)
@ -231,6 +232,10 @@ void S_NoiseDebug (void)
mysnprintf(temp, countof(temp), "%d", chan->EntChannel); mysnprintf(temp, countof(temp), "%d", chan->EntChannel);
screen->DrawText(SmallFont, color, 300, y, temp, TAG_DONE); screen->DrawText(SmallFont, color, 300, y, temp, TAG_DONE);
// Priority
mysnprintf(temp, countof(temp), "%d", chan->Priority);
screen->DrawText(SmallFont, color, 340, y, temp, TAG_DONE);
// Flags // Flags
mysnprintf(temp, countof(temp), "%s3%sZ%sU%sM%sN%sA%sL%sE", mysnprintf(temp, countof(temp), "%s3%sZ%sU%sM%sN%sA%sL%sE",
(chan->ChanFlags & CHAN_IS3D) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHAN_IS3D) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
@ -241,7 +246,7 @@ void S_NoiseDebug (void)
(chan->ChanFlags & CHAN_AREA) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHAN_AREA) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHAN_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK); (chan->ChanFlags & CHAN_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK);
screen->DrawText(SmallFont, color, 340, y, temp, TAG_DONE); screen->DrawText(SmallFont, color, 380, y, temp, TAG_DONE);
y += 8; y += 8;
if (chan->PrevChan == &Channels) if (chan->PrevChan == &Channels)
@ -365,26 +370,18 @@ void S_Start ()
// Check for local sound definitions. Only reload if they differ // Check for local sound definitions. Only reload if they differ
// from the previous ones. // from the previous ones.
const char *LocalSndInfo; FString LocalSndInfo;
const char *LocalSndSeq; FString LocalSndSeq;
// To be certain better check whether level is valid! // To be certain better check whether level is valid!
if (level.info && level.info->soundinfo) if (level.info)
{ {
LocalSndInfo = level.info->soundinfo; LocalSndInfo = level.info->SoundInfo;
}
else
{
LocalSndInfo = "";
} }
if (level.info && level.info->sndseq) if (level.info)
{ {
LocalSndSeq = level.info->sndseq; LocalSndSeq = level.info->SndSeq;
}
else
{
LocalSndSeq = "";
} }
bool parse_ss = false; bool parse_ss = false;
@ -415,11 +412,11 @@ void S_Start ()
{ {
parse_ss = true; parse_ss = true;
} }
if (parse_ss) if (parse_ss)
{ {
S_ParseSndSeq(*LocalSndSeq? Wads.CheckNumForFullName(LocalSndSeq, true) : -1); S_ParseSndSeq(*LocalSndSeq? Wads.CheckNumForFullName(LocalSndSeq, true) : -1);
} }
else
LastLocalSndInfo = LocalSndInfo; LastLocalSndInfo = LocalSndInfo;
LastLocalSndSeq = LocalSndSeq; LastLocalSndSeq = LocalSndSeq;
@ -437,7 +434,7 @@ void S_Start ()
if (!savegamerestore) if (!savegamerestore)
{ {
if (level.cdtrack == 0 || !S_ChangeCDMusic (level.cdtrack, level.cdid)) if (level.cdtrack == 0 || !S_ChangeCDMusic (level.cdtrack, level.cdid))
S_ChangeMusic (level.music, level.musicorder); S_ChangeMusic (level.Music, level.musicorder);
} }
} }
@ -940,7 +937,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
// Select priority. // Select priority.
if (type == SOURCE_None || actor == players[consoleplayer].camera) if (type == SOURCE_None || actor == players[consoleplayer].camera)
{ {
basepriority = 40; basepriority = 80;
} }
else else
{ {
@ -1664,7 +1661,7 @@ void S_EvictAllChannels()
{ {
S_StopChannel(chan); S_StopChannel(chan);
} }
assert(chan->NextChan == next); // assert(chan->NextChan == next);
} }
} }
} }
@ -2165,7 +2162,7 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
{ {
if (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL) if (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL)
{ {
musicname = level.music; musicname = level.Music;
order = level.musicorder; order = level.musicorder;
} }
else else
@ -2428,9 +2425,9 @@ CCMD (idmus)
if ( (info = FindLevelInfo (map)) ) if ( (info = FindLevelInfo (map)) )
{ {
if (info->music) if (info->Music.IsNotEmpty())
{ {
S_ChangeMusic (info->music, info->musicorder); S_ChangeMusic (info->Music, info->musicorder);
Printf ("%s\n", GStrings("STSTR_MUS")); Printf ("%s\n", GStrings("STSTR_MUS"));
} }
} }

View file

@ -22,6 +22,7 @@
#include "m_misc.h" #include "m_misc.h"
#include "templates.h" #include "templates.h"
#include "doomstat.h" #include "doomstat.h"
#include "v_text.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -752,16 +753,21 @@ void FScanner::UnGet ()
// //
//========================================================================== //==========================================================================
int FScanner::MatchString (const char **strings) int FScanner::MatchString (const char **strings, size_t stride)
{ {
int i; int i;
assert(stride % sizeof(const char*) == 0);
stride /= sizeof(const char*);
for (i = 0; *strings != NULL; i++) for (i = 0; *strings != NULL; i++)
{ {
if (Compare (*strings++)) if (Compare (*strings))
{ {
return i; return i;
} }
strings += stride;
} }
return -1; return -1;
} }
@ -772,11 +778,11 @@ int FScanner::MatchString (const char **strings)
// //
//========================================================================== //==========================================================================
int FScanner::MustMatchString (const char **strings) int FScanner::MustMatchString (const char **strings, size_t stride)
{ {
int i; int i;
i = MatchString (strings); i = MatchString (strings, stride);
if (i == -1) if (i == -1)
{ {
ScriptError (NULL); ScriptError (NULL);
@ -1007,7 +1013,7 @@ void STACK_ARGS FScanner::ScriptMessage (const char *message, ...)
va_end (arglist); va_end (arglist);
} }
Printf ("Script error, \"%s\" line %d:\n%s\n", ScriptName.GetChars(), Printf (TEXTCOLOR_RED"Script error, \"%s\" line %d:\n%s\n", ScriptName.GetChars(),
AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); AlreadyGot? AlreadyGotLine : Line, composed.GetChars());
} }

View file

@ -54,8 +54,8 @@ public:
void UnGet(); void UnGet();
bool Compare(const char *text); bool Compare(const char *text);
int MatchString(const char **strings); int MatchString(const char **strings, size_t stride = sizeof(char*));
int MustMatchString(const char **strings); int MustMatchString(const char **strings, size_t stride = sizeof(char*));
int GetMessageLine(); int GetMessageLine();
void ScriptError(const char *message, ...); void ScriptError(const char *message, ...);

View file

@ -281,6 +281,25 @@ static void MouseRead ()
} }
} }
static void WheelMoved(event_t *event)
{
if (GUICapture)
{
SDLMod mod = SDL_GetModState();
event->type = EV_GUI_Event;
event->subtype = event->data1 == KEY_MWHEELUP ? EV_GUI_WheelUp : EV_GUI_WheelDown;
event->data1 = 0;
event->data3 = ((mod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
((mod & KMOD_CTRL) ? GKM_CTRL : 0) |
((mod & KMOD_ALT) ? GKM_ALT : 0);
D_PostEvent(event);
}
else
{
D_PostEvent(event);
}
}
CUSTOM_CVAR(Int, mouse_capturemode, 1, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) CUSTOM_CVAR(Int, mouse_capturemode, 1, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
{ {
if (self < 0) self = 0; if (self < 0) self = 0;
@ -316,7 +335,7 @@ static void I_CheckNativeMouse ()
{ {
SDL_ShowCursor (1); SDL_ShowCursor (1);
SDL_WM_GrabInput (SDL_GRAB_OFF); SDL_WM_GrabInput (SDL_GRAB_OFF);
FlushDIKState (KEY_MOUSE1, KEY_MOUSE4); FlushDIKState (KEY_MOUSE1, KEY_MOUSE8);
} }
else else
{ {
@ -358,6 +377,12 @@ void MessagePump (const SDL_Event &sev)
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp; event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
/* These button mappings work with my Gentoo system using the
* evdev driver and a Logitech MX510 mouse. Whether or not they
* carry over to other Linux systems, I have no idea, but I sure
* hope so. (Though buttons 11 and 12 are kind of useless, since
* they also trigger buttons 4 and 5.)
*/
switch (sev.button.button) switch (sev.button.button)
{ {
case 1: event.data1 = KEY_MOUSE1; break; case 1: event.data1 = KEY_MOUSE1; break;
@ -365,10 +390,28 @@ void MessagePump (const SDL_Event &sev)
case 3: event.data1 = KEY_MOUSE2; break; case 3: event.data1 = KEY_MOUSE2; break;
case 4: event.data1 = KEY_MWHEELUP; break; case 4: event.data1 = KEY_MWHEELUP; break;
case 5: event.data1 = KEY_MWHEELDOWN; break; case 5: event.data1 = KEY_MWHEELDOWN; break;
case 6: event.data1 = KEY_MOUSE4; break; /* dunno */ case 6: event.data1 = KEY_MOUSE4; break; /* dunno; not generated by my mouse */
case 7: event.data1 = KEY_MOUSE5; break; /* ditto */
case 8: event.data1 = KEY_MOUSE4; break;
case 9: event.data1 = KEY_MOUSE5; break;
case 10: event.data1 = KEY_MOUSE6; break;
case 11: event.data1 = KEY_MOUSE7; break;
case 12: event.data1 = KEY_MOUSE8; break;
default: printf("SDL mouse button %s %d\n",
sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break;
}
if (event.data1 != 0)
{
//DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown);
if (event.data1 == KEY_MWHEELUP || event.data1 == KEY_MWHEELDOWN)
{
WheelMoved(&event);
}
else
{
D_PostEvent(&event);
}
} }
//DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown);
D_PostEvent (&event);
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:

View file

@ -228,7 +228,6 @@ void I_Quit (void)
if (demorecording) if (demorecording)
G_CheckDemoStatus(); G_CheckDemoStatus();
G_ClearSnapshots ();
} }

View file

@ -805,7 +805,7 @@ bool FMODSoundRenderer::Init()
} }
for (;;) for (;;)
{ {
result = Sys->init(snd_channels + NUM_EXTRA_SOFTWARE_CHANNELS, initflags, 0); result = Sys->init(MAX(*snd_channels, MAX_CHANNELS), initflags, 0);
if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) if (result == FMOD_ERR_OUTPUT_CREATEBUFFER)
{ {
// Possible causes of a buffer creation failure: // Possible causes of a buffer creation failure:
@ -1435,7 +1435,7 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *
GDistScale = distscale; GDistScale = distscale;
// Experiments indicate that playSound will ignore priorities and always succeed // Experiments indicate that playSound will ignore priorities and always succeed
// as long as the paremeters are set properly. It will first try to kick out sounds // as long as the parameters are set properly. It will first try to kick out sounds
// with the same priority level but has no problem with kicking out sounds at // with the same priority level but has no problem with kicking out sounds at
// higher priority levels if it needs to. // higher priority levels if it needs to.
result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx.data, true, &chan); result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx.data, true, &chan);
@ -1488,6 +1488,7 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *
return NULL; return NULL;
} }
chan->setPaused(false); chan->setPaused(false);
chan->getPriority(&def_priority);
FISoundChannel *schan = CommonChannelSetup(chan, reuse_chan); FISoundChannel *schan = CommonChannelSetup(chan, reuse_chan);
schan->Rolloff = *rolloff; schan->Rolloff = *rolloff;
return schan; return schan;

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the // This file was automatically generated by the
// updaterevision tool. Do not edit by hand. // updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "1369" #define ZD_SVN_REVISION_STRING "1401"
#define ZD_SVN_REVISION_NUMBER 1369 #define ZD_SVN_REVISION_NUMBER 1401

View file

@ -1,9 +1,9 @@
/* /*
** teaminfo.cpp ** teaminfo.cpp
** Implementation of the TEAMINFO lump. ** Parses TEAMINFO and manages teams.
** **
**--------------------------------------------------------------------------- **---------------------------------------------------------------------------
** Copyright 2007-2008 Christopher Westley ** Copyright 2007-2009 Christopher Westley
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without ** Redistribution and use in source and binary forms, with or without
@ -34,12 +34,12 @@
// HEADER FILES ------------------------------------------------------------ // HEADER FILES ------------------------------------------------------------
#include "c_dispatch.h"
#include "gi.h"
#include "i_system.h" #include "i_system.h"
#include "sc_man.h"
#include "teaminfo.h" #include "teaminfo.h"
#include "v_video.h"
#include "v_palette.h"
#include "v_font.h" #include "v_font.h"
#include "v_video.h"
#include "w_wad.h" #include "w_wad.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -50,136 +50,300 @@
// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
void TEAMINFO_Init ();
void TEAMINFO_ParseTeam (FScanner &sc);
bool TEAMINFO_IsValidTeam (int team);
// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
// EXTERNAL DATA DECLARATIONS ---------------------------------------------- // EXTERNAL DATA DECLARATIONS ----------------------------------------------
// PUBLIC DATA DEFINITIONS ------------------------------------------------- // PUBLIC DATA DEFINITIONS -------------------------------------------------
TArray <TEAMINFO> teams; FTeam TeamLibrary;
TArray<FTeam> Teams;
// PRIVATE DATA DEFINITIONS ------------------------------------------------ // PRIVATE DATA DEFINITIONS ------------------------------------------------
static const char *keywords_teaminfo [] = { static const char *TeamInfoOptions[] =
"PLAYERCOLOR", {
"TEXTCOLOR", "Game",
"LOGO", "PlayerColor",
NULL "TextColor",
"Logo",
"AllowCustomPlayerColor",
"RailColor",
"FlagItem",
"SkullItem",
"PlayerStartThingNumber",
"SmallFlagHUDIcon",
"SmallSkullHUDIcon",
"LargeFlagHUDIcon",
"LargeSkullHUDIcon",
"WinnerPic",
"LoserPic",
"WinnerTheme",
"LoserTheme",
};
enum ETeamOptions
{
TEAMINFO_Game,
TEAMINFO_PlayerColor,
TEAMINFO_TextColor,
TEAMINFO_Logo,
TEAMINFO_AllowCustomPlayerColor,
TEAMINFO_RailColor,
TEAMINFO_FlagItem,
TEAMINFO_SkullItem,
TEAMINFO_PlayerStartThingNumber,
TEAMINFO_SmallFlagHUDIcon,
TEAMINFO_SmallSkullHUDIcon,
TEAMINFO_LargeFlagHUDIcon,
TEAMINFO_LargeSkullHUDIcon,
TEAMINFO_WinnerPic,
TEAMINFO_LoserPic,
TEAMINFO_WinnerTheme,
TEAMINFO_LoserTheme,
}; };
// CODE -------------------------------------------------------------------- // CODE --------------------------------------------------------------------
//========================================================================== //==========================================================================
// //
// TEAMINFO_Init // FTeam :: FTeam
// //
//========================================================================== //==========================================================================
void TEAMINFO_Init () FTeam::FTeam ()
{ {
int lastlump = 0, lump; m_GameFilter = 0;
m_iPlayerColor = 0;
while ((lump = Wads.FindLump ("TEAMINFO", &lastlump)) != -1) m_iPlayerCount = 0;
{ m_iScore = 0;
FScanner sc(lump); m_iPresent = 0;
while (sc.GetString ()) m_iTies = 0;
{ m_bAllowCustomPlayerColor = false;
if (sc.Compare("CLEARTEAMS"))
teams.Clear ();
else if (sc.Compare("TEAM"))
TEAMINFO_ParseTeam (sc);
else
sc.ScriptError ("Unknown command %s in TEAMINFO", sc.String);
}
}
if (teams.Size () < 2)
I_FatalError ("At least two teams must be defined in TEAMINFO");
} }
//========================================================================== //==========================================================================
// //
// TEAMINFO_ParseTeam // FTeam :: ParseTeamInfo
// //
//========================================================================== //==========================================================================
void TEAMINFO_ParseTeam (FScanner &sc) void FTeam::ParseTeamInfo ()
{ {
TEAMINFO team; int iLump, iLastLump = 0;
int i;
sc.MustGetString (); while ((iLump = Wads.FindLump ("TEAMINFO", &iLastLump)) != -1)
team.name = sc.String;
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{ {
sc.MustGetString(); FScanner Scan (iLump);
switch(i = sc.MatchString (keywords_teaminfo))
while (Scan.GetString ())
{ {
case 0: if (Scan.Compare ("ClearTeams"))
sc.MustGetString (); ClearTeams ();
team.playercolor = V_GetColor (NULL, sc.String); else if (Scan.Compare ("Team"))
ParseTeamDefinition (Scan);
else
Scan.ScriptError ("ParseTeamInfo: Unknown team command '%s'.\n", Scan.String);
}
}
if (Teams.Size () < 2)
I_FatalError ("ParseTeamInfo: At least two teams must be defined in TEAMINFO.");
else if (Teams.Size () > TEAM_MAXIMUM)
I_FatalError ("ParseTeamInfo: Too many teams defined. (Maximum: %d)", TEAM_MAXIMUM);
}
//==========================================================================
//
// FTeam :: ParseTeamDefinition
//
//==========================================================================
void FTeam::ParseTeamDefinition (FScanner &Scan)
{
FTeam Team;
Scan.MustGetString ();
Team.m_Name = Scan.String;
Scan.MustGetStringName ("{");
while (!Scan.CheckString ("}"))
{
Scan.MustGetString ();
switch (Scan.MatchString (TeamInfoOptions))
{
case TEAMINFO_Game:
Scan.MustGetString ();
if (!stricmp (Scan.String, "Doom"))
Team.m_GameFilter |= GAME_Doom;
else if (!stricmp (Scan.String, "Heretic"))
Team.m_GameFilter |= GAME_Heretic;
else if (!stricmp (Scan.String, "Hexen"))
Team.m_GameFilter |= GAME_Hexen;
else if (!stricmp (Scan.String, "Raven"))
Team.m_GameFilter |= GAME_Raven;
else if (!stricmp (Scan.String, "Strife"))
Team.m_GameFilter |= GAME_Strife;
else if (!stricmp (Scan.String, "Chex"))
Team.m_GameFilter |= GAME_Chex;
else if (!stricmp (Scan.String, "Any"))
Team.m_GameFilter |= GAME_Any;
else
Scan.ScriptError ("ParseTeamDefinition: Unknown game type '%s'.\n", Scan.String);
break; break;
case 1: case TEAMINFO_PlayerColor:
sc.MustGetString(); Scan.MustGetString ();
team.textcolor = '['; Team.m_iPlayerColor = V_GetColor (NULL, Scan.String);
team.textcolor << sc.String << ']';
break; break;
case 2: case TEAMINFO_TextColor:
sc.MustGetString (); Scan.MustGetString ();
team.logo = sc.String; Team.m_TextColor.AppendFormat ("[%s]", Scan.String);
break;
case TEAMINFO_Logo:
Scan.MustGetString ();
Team.m_Logo = Scan.String;
break;
case TEAMINFO_AllowCustomPlayerColor:
Team.m_bAllowCustomPlayerColor = true;
break;
case TEAMINFO_PlayerStartThingNumber:
Scan.MustGetNumber ();
break;
case TEAMINFO_RailColor:
case TEAMINFO_FlagItem:
case TEAMINFO_SkullItem:
case TEAMINFO_SmallFlagHUDIcon:
case TEAMINFO_SmallSkullHUDIcon:
case TEAMINFO_LargeFlagHUDIcon:
case TEAMINFO_LargeSkullHUDIcon:
case TEAMINFO_WinnerPic:
case TEAMINFO_LoserPic:
case TEAMINFO_WinnerTheme:
case TEAMINFO_LoserTheme:
Scan.MustGetString ();
break; break;
default: default:
Scan.ScriptError ("ParseTeamDefinition: Unknown team option '%s'.\n", Scan.String);
break; break;
} }
} }
teams.Push (team); if (Team.m_GameFilter == 0 || Team.m_GameFilter & gameinfo.gametype)
Teams.Push (Team);
} }
//========================================================================== //==========================================================================
// //
// TEAMINFO_IsValidTeam // FTeam :: ClearTeams
// //
//========================================================================== //==========================================================================
bool TEAMINFO_IsValidTeam (int team) void FTeam::ClearTeams ()
{ {
if (team < 0 || team >= (signed)teams.Size ()) Teams.Clear ();
{ }
//==========================================================================
//
// FTeam :: IsValidTeam
//
//==========================================================================
bool FTeam::IsValidTeam (unsigned int uiTeam)
{
if (uiTeam < 0 || uiTeam >= Teams.Size ())
return false; return false;
}
return true; return true;
} }
//========================================================================== //==========================================================================
// //
// TEAMINFO :: GetTextColor // FTeam :: GetName
// //
//========================================================================== //==========================================================================
int TEAMINFO::GetTextColor () const const char *FTeam::GetName () const
{ {
if (textcolor.IsEmpty()) return m_Name;
}
//==========================================================================
//
// FTeam :: GetPlayerColor
//
//==========================================================================
int FTeam::GetPlayerColor () const
{
return m_iPlayerColor;
}
//==========================================================================
//
// FTeam :: GetTextColor
//
//==========================================================================
int FTeam::GetTextColor () const
{
if (m_TextColor.IsEmpty ())
return CR_UNTRANSLATED;
const BYTE *pColor = (const BYTE *)m_TextColor.GetChars ();
int iColor = V_ParseFontColor (pColor, 0, 0);
if (iColor == CR_UNDEFINED)
{ {
Printf ("GetTextColor: Undefined color '%s' in definition of team '%s'.\n", m_TextColor.GetChars (), m_Name.GetChars ());
return CR_UNTRANSLATED; return CR_UNTRANSLATED;
} }
const BYTE *cp = (const BYTE *)textcolor.GetChars();
int color = V_ParseFontColor(cp, 0, 0); return iColor;
if (color == CR_UNDEFINED) }
{
Printf("Undefined color '%s' in definition of team %s\n", textcolor.GetChars (), name.GetChars ()); //==========================================================================
color = CR_UNTRANSLATED; //
} // FTeam :: GetLogo
return color; //
//==========================================================================
FString FTeam::GetLogo () const
{
return m_Logo;
}
//==========================================================================
//
// FTeam :: GetAllowCustomPlayerColor
//
//==========================================================================
bool FTeam::GetAllowCustomPlayerColor () const
{
return m_bAllowCustomPlayerColor;
}
//==========================================================================
//
// CCMD teamlist
//
//==========================================================================
CCMD (teamlist)
{
Printf ("Defined teams are as follows:\n");
for (unsigned int uiTeam = 0; uiTeam < Teams.Size (); uiTeam++)
Printf ("%d : %s\n", uiTeam, Teams[uiTeam].GetName ());
Printf ("End of team list.\n");
} }

View file

@ -1,9 +1,9 @@
/* /*
** teaminfo.h ** teaminfo.h
** Implementation of the TEAMINFO lump. ** Parses TEAMINFO and manages teams.
** **
**--------------------------------------------------------------------------- **---------------------------------------------------------------------------
** Copyright 2007-2008 Christopher Westley ** Copyright 2007-2009 Christopher Westley
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without ** Redistribution and use in source and binary forms, with or without
@ -35,28 +35,43 @@
#ifndef __TEAMINFO_H__ #ifndef __TEAMINFO_H__
#define __TEAMINFO_H__ #define __TEAMINFO_H__
#define TEAM_None 255
#include "doomtype.h" #include "doomtype.h"
#include "sc_man.h"
struct TEAMINFO const int TEAM_NONE = 255;
const int TEAM_MAXIMUM = 16;
class FTeam
{ {
FString name; public:
int playercolor; FTeam ();
FString textcolor; void ParseTeamInfo ();
int GetTextColor () const; bool IsValidTeam (unsigned int uiTeam);
FString logo;
int players; const char *GetName () const;
int score; int GetPlayerColor () const;
int present; int GetTextColor () const;
int ties; FString GetLogo () const;
bool GetAllowCustomPlayerColor () const;
int m_iPlayerCount;
int m_iScore;
int m_iPresent;
int m_iTies;
private:
void ParseTeamDefinition (FScanner &Scan);
void ClearTeams ();
FString m_Name;
BYTE m_GameFilter;
int m_iPlayerColor;
FString m_TextColor;
FString m_Logo;
bool m_bAllowCustomPlayerColor;
}; };
extern TArray <TEAMINFO> teams; extern FTeam TeamLibrary;
extern TArray<FTeam> Teams;
extern void TEAMINFO_Init ();
extern void TEAMINFO_ParseTeam ();
extern bool TEAMINFO_IsValidTeam (int team);
#endif #endif

View file

@ -268,7 +268,7 @@ static void FinishThingdef()
// Skip non-actors // Skip non-actors
if (!ti->IsDescendantOf(RUNTIME_CLASS(AActor))) continue; if (!ti->IsDescendantOf(RUNTIME_CLASS(AActor))) continue;
if (ti->Size == -1) if (ti->Size == (unsigned)-1)
{ {
Printf("Class %s referenced but not defined\n", ti->TypeName.GetChars()); Printf("Class %s referenced but not defined\n", ti->TypeName.GetChars());
errorcount++; errorcount++;

View file

@ -124,7 +124,7 @@ public:
void Copy(int dest, int src, int cnt); void Copy(int dest, int src, int cnt);
int ResolveAll(); int ResolveAll();
FxExpression *Get(int no); FxExpression *Get(int no);
int Size() { return expressions.Size(); } unsigned int Size() { return expressions.Size(); }
}; };
extern FStateExpressions StateParams; extern FStateExpressions StateParams;

View file

@ -77,7 +77,7 @@
// SAVESIG should match SAVEVER. // SAVESIG should match SAVEVER.
// MINSAVEVER is the minimum level snapshot version that can be loaded. // MINSAVEVER is the minimum level snapshot version that can be loaded.
#define MINSAVEVER 1304 #define MINSAVEVER 1393
#if ZD_SVN_REVISION_NUMBER < MINSAVEVER #if ZD_SVN_REVISION_NUMBER < MINSAVEVER
// Never write a savegame with a version lower than what we need // Never write a savegame with a version lower than what we need

View file

@ -230,7 +230,7 @@ static FTexture* p; // Player graphic
static FTexture* lnames[2]; // Name graphics of each level (centered) static FTexture* lnames[2]; // Name graphics of each level (centered)
// [RH] Info to dynamically generate the level name graphics // [RH] Info to dynamically generate the level name graphics
static const char *lnametexts[2]; static FString lnametexts[2];
static FTexture *background; static FTexture *background;
@ -297,11 +297,11 @@ void WI_LoadBackground(bool isenterpic)
if (isenterpic) if (isenterpic)
{ {
level_info_t * li = FindLevelInfo(wbs->next); level_info_t * li = FindLevelInfo(wbs->next);
if (li != NULL) lumpname = li->enterpic; if (li != NULL) lumpname = li->EnterPic;
} }
else else
{ {
lumpname = level.info->exitpic; lumpname = level.info->ExitPic;
} }
// Try to get a default if nothing specified // Try to get a default if nothing specified
@ -329,7 +329,7 @@ void WI_LoadBackground(bool isenterpic)
// If going from E1-E3 to E4 the default should be used, not the exit pic. // If going from E1-E3 to E4 the default should be used, not the exit pic.
// Not if the exit pic is user defined! // Not if the exit pic is user defined!
if (level.info->exitpic != NULL && level.info->exitpic[0]!=0) return; if (level.info->ExitPic.IsNotEmpty()) return;
// E1-E3 need special treatment when playing Doom 1. // E1-E3 need special treatment when playing Doom 1.
if (gamemode!=commercial) if (gamemode!=commercial)
@ -712,6 +712,7 @@ int WI_DrawName(int y, const char *levelname)
lumph = BigFont->GetHeight() * CleanYfac; lumph = BigFont->GetHeight() * CleanYfac;
p = levelname; p = levelname;
if (!p) return 0;
l = strlen(p); l = strlen(p);
if (!l) return 0; if (!l) return 0;
@ -1885,8 +1886,8 @@ void WI_Ticker(void)
if (bcnt == 1) if (bcnt == 1)
{ {
// intermission music - use the defaults if none specified // intermission music - use the defaults if none specified
if (level.info->intermusic != NULL) if (level.info->InterMusic.IsNotEmpty())
S_ChangeMusic(level.info->intermusic, level.info->intermusicorder); S_ChangeMusic(level.info->InterMusic, level.info->intermusicorder);
else if (gameinfo.gametype == GAME_Heretic) else if (gameinfo.gametype == GAME_Heretic)
S_ChangeMusic ("mus_intr"); S_ChangeMusic ("mus_intr");
else if (gameinfo.gametype == GAME_Hexen) else if (gameinfo.gametype == GAME_Hexen)
@ -1966,11 +1967,12 @@ void WI_loadData(void)
bstar = star; bstar = star;
} }
// Use the local level structure which can be overridden by hubs if they eventually get names! // Use the local level structure which can be overridden by hubs
lnametexts[0] = level.level_name; lnametexts[0] = level.LevelName;
level_info_t *li = FindLevelInfo(wbs->next); level_info_t *li = FindLevelInfo(wbs->next);
lnametexts[1] = li ? G_MaybeLookupLevelName(li) : NULL; if (li) lnametexts[1] = li->LookupLevelName();
else lnametexts[1] = "";
WI_LoadBackground(false); WI_LoadBackground(false);
} }

View file

@ -2405,18 +2405,7 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi
float u1 = tex->Box->Right; float u1 = tex->Box->Right;
float v1 = tex->Box->Bottom; float v1 = tex->Box->Bottom;
float uscale = 1.f / tex->Box->Owner->Width; float uscale = 1.f / tex->Box->Owner->Width;
float vscale = 1.f / tex->Box->Owner->Height / yscale; bool scissoring = false;
if (y0 < parms.uclip)
{
v0 += (float(parms.uclip) - y0) * vscale;
y0 = float(parms.uclip);
}
if (y1 > parms.dclip)
{
v1 -= (y1 - float(parms.dclip)) * vscale;
y1 = float(parms.dclip);
}
if (parms.flipX) if (parms.flipX)
{ {
@ -2429,16 +2418,45 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi
x1 -= (parms.texwidth - parms.windowright) * xscale; x1 -= (parms.texwidth - parms.windowright) * xscale;
u1 -= (parms.texwidth - parms.windowright) * uscale; u1 -= (parms.texwidth - parms.windowright) * uscale;
} }
#if 0
float vscale = 1.f / tex->Box->Owner->Height / yscale;
if (y0 < parms.uclip)
{
v0 += (float(parms.uclip) - y0) * vscale;
y0 = float(parms.uclip);
}
if (y1 > parms.dclip)
{
v1 -= (y1 - float(parms.dclip)) * vscale;
y1 = float(parms.dclip);
}
if (x0 < parms.lclip) if (x0 < parms.lclip)
{ {
u0 += float(parms.lclip - x0) * uscale / xscale; u0 += float(parms.lclip - x0) * uscale / xscale * 2;
x0 = float(parms.lclip); x0 = float(parms.lclip);
} }
if (x1 > parms.rclip) if (x1 > parms.rclip)
{ {
u1 -= float(x1 - parms.rclip) * uscale / xscale; u1 -= (x1 - parms.rclip) * uscale / xscale * 2;
x1 = float(parms.rclip); x1 = float(parms.rclip);
} }
#else
// Use a scissor test because the math above introduces some jitter
// that is noticeable at low resolutions. Unfortunately, this means this
// quad has to be in a batch by itself.
if (y0 < parms.uclip || y1 > parms.dclip || x0 < parms.lclip || x1 > parms.rclip)
{
scissoring = true;
if (QuadBatchPos > 0)
{
EndQuadBatch();
BeginQuadBatch();
}
RECT scissor = { parms.lclip, parms.uclip, parms.rclip, parms.dclip };
D3DDevice->SetScissorRect(&scissor);
D3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
}
#endif
parms.bilinear = false; parms.bilinear = false;
D3DCOLOR color0, color1; D3DCOLOR color0, color1;
@ -2511,6 +2529,12 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi
QuadBatchPos++; QuadBatchPos++;
VertexPos += 4; VertexPos += 4;
IndexPos += 6; IndexPos += 6;
if (scissoring)
{
EndQuadBatch();
D3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
}
} }
//========================================================================== //==========================================================================

View file

@ -449,7 +449,6 @@ void I_Quit (void)
if (demorecording) if (demorecording)
G_CheckDemoStatus(); G_CheckDemoStatus();
G_ClearSnapshots ();
} }

View file

@ -1110,6 +1110,7 @@ void FString::ReallocBuffer (size_t newlen)
#include <windows.h> #include <windows.h>
static HANDLE StringHeap; static HANDLE StringHeap;
const SIZE_T STRING_HEAP_SIZE = 64*1024;
#endif #endif
FStringData *FStringData::Alloc (size_t strlen) FStringData *FStringData::Alloc (size_t strlen)
@ -1120,7 +1121,7 @@ FStringData *FStringData::Alloc (size_t strlen)
#ifdef _WIN32 #ifdef _WIN32
if (StringHeap == NULL) if (StringHeap == NULL)
{ {
StringHeap = HeapCreate (0, 64*1024, 0); StringHeap = HeapCreate (0, STRING_HEAP_SIZE, 0);
if (StringHeap == NULL) if (StringHeap == NULL)
{ {
throw std::bad_alloc(); throw std::bad_alloc();

View file

@ -13,7 +13,7 @@ const int SXF_ABSOLUTEMOMENTUM=8;
const int SXF_SETMASTER=16; const int SXF_SETMASTER=16;
const int SXF_NOCHECKPOSITION = 32; const int SXF_NOCHECKPOSITION = 32;
const int SXF_TELEFRAG=64; const int SXF_TELEFRAG=64;
// 128 was uses by Skulltag const int SXF_CLIENTSPAWN=128; // only used by Skulltag
const int SXF_TRANSFERAMBUSHFLAG=256; const int SXF_TRANSFERAMBUSHFLAG=256;
// Flags for A_Chase // Flags for A_Chase

View file

@ -327,6 +327,8 @@ Actor Weapon : Inventory native
ACTOR WeaponGiver : Weapon native ACTOR WeaponGiver : Weapon native
{ {
Weapon.AmmoGive1 -1
Weapon.AmmoGive2 -1
} }
Actor WeaponHolder : Inventory native Actor WeaponHolder : Inventory native

View file

@ -772,6 +772,30 @@ decal CrossbowScorch2
randomflipy randomflipy
} }
/***** Phoenix Rod, flamethrower mode **************************************/
decal PhoenixThrowerScorch
{
pic CBALSCR1
shade "00 00 00"
x-scale 0.4
y-scale 0.4
randomflipx
randomflipy
}
/***** "Horn Rod", rain maker projectile ***********************************/
decal HornyRainMaker
{
pic TWIRL
shade "00 00 00"
x-scale 0.7
y-scale 0.7
randomflipx
randomflipy
}
/***** Centaur Scorches ****************************************************/ /***** Centaur Scorches ****************************************************/
decal CentaurScorch decal CentaurScorch
@ -990,15 +1014,17 @@ generator GoldWand RailScorchLower
generator GoldWandPowered RailScorchLower generator GoldWandPowered RailScorchLower
generator GoldWandFX1 HImpScorch generator GoldWandFX1 HImpScorch
generator CrossbowFX1 CrossbowScorch generator CrossbowFX1 CrossbowScorch
generator CrossbowFX2 CrossbowScorch
generator CrossbowFX3 CrossbowScorch2 generator CrossbowFX3 CrossbowScorch2
generator MaceFX1 BaronScorch generator MaceFX1 BaronScorch
generator MaceFX4 BFGScorch
generator Blaster RailScorchLower generator Blaster RailScorchLower
generator BlasterFX1 HImpScorch generator BlasterFX1 HImpScorch
generator Ripper HImpScorch generator Ripper HImpScorch
generator HornRodFX1 PlasmaScorchLower generator HornRodFX1 PlasmaScorchLower
generator HornRodFX2 PlasmaScorchLower generator HornRodFX2 HornyRainMaker
generator PhoenixFX1 Scorch generator PhoenixFX1 Scorch
generator PhoenixFX2 Scorch generator PhoenixFX2 PhoenixThrowerScorch
generator CStaffMissile DoomImpScorch generator CStaffMissile DoomImpScorch
generator HammerMissile Scorch generator HammerMissile Scorch

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Before After
Before After