Merge remote-tracking branch 'origin/openal' into openal

Conflicts:
	src/sound/fmodsound.cpp
	src/sound/oalsound.cpp
	src/sound/oalsound.h
This commit is contained in:
Chris Robinson 2014-06-15 09:59:24 -07:00
commit 0e21057a2a
97 changed files with 1119 additions and 350 deletions

View File

@ -1,6 +1,39 @@
cmake_minimum_required( VERSION 2.4 )
project(ZDoom)
# Generator expression are available some time in CMake 2.8. Due to
# cmake_minimum_required, we can assume a minor version of > 7 implies major >= 2
if(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7)
option( NO_GENERATOR_EXPRESSIONS "Disable generator expressions (for building pk3s with IDEs)." OFF )
else(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7)
set( NO_GENERATOR_EXPRESSIONS ON )
endif(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7)
# Simplify pk3 building, add_pk3(filename srcdirectory)
function( add_pk3 PK3_NAME PK3_DIR )
get_target_property(ZIPDIR_EXE zipdir LOCATION)
# Generate target name. Just use "pk3" for main pk3 target.
string( REPLACE "." "_" PK3_TARGET ${PK3_NAME} )
if( ${PK3_TARGET} STREQUAL "zdoom_pk3" )
set( PK3_TARGET "pk3" )
endif( ${PK3_TARGET} STREQUAL "zdoom_pk3" )
if( NO_GENERATOR_EXPRESSIONS )
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $<TARGET_FILE_DIR:zdoom>
DEPENDS zipdir ${PK3_DIR} )
else( NO_GENERATOR_EXPRESSIONS )
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
DEPENDS zipdir ${PK3_DIR} )
endif( NO_GENERATOR_EXPRESSIONS )
add_custom_target( ${PK3_TARGET} ALL
DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} )
endfunction( add_pk3 )
IF( NOT CMAKE_BUILD_TYPE )
SET( CMAKE_BUILD_TYPE Debug CACHE STRING
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."

View File

@ -44,7 +44,7 @@
#define DUMB_VERSION_STR "0.9.3"
#define DUMB_NAME "DUMB v"DUMB_VERSION_STR
#define DUMB_NAME "DUMB v" DUMB_VERSION_STR
#define DUMB_YEAR 2005
#define DUMB_MONTH 8
@ -56,13 +56,13 @@
#define DUMB_DAY_STR1 "7"
#if DUMB_MONTH < 10
#define DUMB_MONTH_STR2 "0"DUMB_MONTH_STR1
#define DUMB_MONTH_STR2 "0" DUMB_MONTH_STR1
#else
#define DUMB_MONTH_STR2 DUMB_MONTH_STR1
#endif
#if DUMB_DAY < 10
#define DUMB_DAY_STR2 "0"DUMB_DAY_STR1
#define DUMB_DAY_STR2 "0" DUMB_DAY_STR1
#else
#define DUMB_DAY_STR2 DUMB_DAY_STR1
#endif
@ -74,7 +74,7 @@
*/
#define DUMB_DATE (DUMB_YEAR*10000 + DUMB_MONTH*100 + DUMB_DAY)
#define DUMB_DATE_STR DUMB_DAY_STR1"."DUMB_MONTH_STR1"."DUMB_YEAR_STR4
#define DUMB_DATE_STR DUMB_DAY_STR1 "." DUMB_MONTH_STR1 "." DUMB_YEAR_STR4
#undef MIN

View File

@ -650,8 +650,8 @@ static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int rstrict)
if ( ( rstrict & 2 ) )
{
long total_sample_size;
long remain;
int32 total_sample_size;
int32 remain;
rem = f;
f = dumbfile_buffer_mod_2(rem, sigdata->n_samples, sigdata->sample, &total_sample_size, &remain);
if (!f) {

View File

@ -436,7 +436,7 @@ static int limit_xm_getc(void *f)
static long limit_xm_getnc(char *ptr, int32 n, void *f)
static int32 limit_xm_getnc(char *ptr, int32 n, void *f)
{
LIMITED_XM *lx = f;
int left;

View File

@ -113,6 +113,7 @@ Note: All <bool> fields default to false unless mentioned otherwise.
blockprojectiles = <bool>;// Line blocks all projectiles
blockuse = <bool>; // Line blocks all use actions
blocksight = <bool>; // Line blocks monster line of sight
blockhitscan = <bool>; // Line blocks hitscan attacks
locknumber = <int>; // Line special is locked
arg0str = <string>; // Alternate string-based version of arg0
@ -186,6 +187,7 @@ Note: All <bool> fields default to false unless mentioned otherwise.
soundsequence = <string>; // The sound sequence to play when this sector moves. Placing a
// sound sequence thing in the sector will override this property.
hidden = <bool>; // if true this sector will not be drawn on the textured automap.
waterzone = <bool>; // Sector is under water and swimmable
* Note about dropactors
@ -203,6 +205,8 @@ Note: All <bool> fields default to false unless mentioned otherwise.
// Parameter is the conversation ID, 0 meaning none.
countsecret = <bool>; // Picking up this actor counts as a secret.
arg0str = <string>; // Alternate string-based version of arg0
gravity = <float>; // Set per-actor gravity. Positive values are multiplied with the class's property,
// negative values are used as their absolute. Default = 1.0.
* Note about arg0str
@ -328,6 +332,9 @@ Added back locknumber property.
1.20 25.02.2012
Added arg0str thing property.
1.21 09.08.2013
Added waterzone sector property.
===============================================================================
EOF
===============================================================================

View File

@ -9,7 +9,12 @@ include( CheckFunctionExists )
include( CheckCXXCompilerFlag )
include( FindPkgConfig )
option( NO_ASM "Disable assembly code" )
if( NOT APPLE )
option( NO_ASM "Disable assembly code" OFF )
else( NOT APPLE )
# At the moment asm code doesn't work with OS X, so disable by default
option( NO_ASM "Disable assembly code" ON )
endif( NOT APPLE )
if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
option( NO_STRIP "Do not strip Release or MinSizeRel builds" )
# At least some versions of Xcode fail if you strip with the linker
@ -71,8 +76,11 @@ if( WIN32 )
set( FMOD_SEARCH_PATHS
"C:/Program Files/FMOD SoundSystem/FMOD Programmers API ${WIN_TYPE}/api"
"C:/Program Files (x86)/FMOD SoundSystem/FMOD Programmers API ${WIN_TYPE}/api"
# This next one is for me.
"E:/Software/Dev/FMOD/${WIN_TYPE}/api" )
# This next one is for Randy.
"E:/Software/Dev/FMOD/${WIN_TYPE}/api"
# .. and this one for Graf Zahl
"D:/portable/FMOD SoundSystem 4.26/FMOD Programmers API WIN32/api"
)
set( FMOD_INC_PATH_SUFFIXES PATH_SUFFIXES inc )
set( FMOD_LIB_PATH_SUFFIXES PATH_SUFFIXES lib )
set( NASM_NAMES nasmw nasm )

View File

@ -268,7 +268,7 @@ enum
MF5_DONTDRAIN = 0x00000001, // cannot be drained health from.
/* = 0x00000002, */
MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
/* = 0x00000008, */
MF5_NOFORWARDFALL = 0x00000008, // Does not make any actor fall forward by being damaged by this
MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret
MF5_AVOIDINGDROPOFF = 0x00000020, // Used to move monsters away from dropoffs
MF5_NODAMAGE = 0x00000040, // Actor can be shot and reacts to being shot but takes no damage
@ -331,6 +331,7 @@ enum
MF6_DOHARMSPECIES = 0x08000000, // Do hurt one's own species with projectiles.
MF6_INTRYMOVE = 0x10000000, // Executing P_TryMove
MF6_NOTAUTOAIMED = 0x20000000, // Do not subject actor to player autoaim.
MF6_NOTONAUTOMAP = 0x40000000, // will not be shown on automap with the 'scanner' powerup.
// --- mobj.renderflags ---

View File

@ -186,6 +186,9 @@ CVAR (Color, am_ovwallcolor, 0x00ff00, CVAR_ARCHIVE);
CVAR (Color, am_ovspecialwallcolor, 0xffffff, CVAR_ARCHIVE);
CVAR (Color, am_ovthingcolor, 0xe88800, CVAR_ARCHIVE);
CVAR (Color, am_ovotherwallscolor, 0x008844, CVAR_ARCHIVE);
CVAR (Color, am_ovefwallcolor, 0x008844, CVAR_ARCHIVE);
CVAR (Color, am_ovfdwallcolor, 0x008844, CVAR_ARCHIVE);
CVAR (Color, am_ovcdwallcolor, 0x008844, CVAR_ARCHIVE);
CVAR (Color, am_ovunseencolor, 0x00226e, CVAR_ARCHIVE);
CVAR (Color, am_ovtelecolor, 0xffff00, CVAR_ARCHIVE);
CVAR (Color, am_intralevelcolor, 0x0000ff, CVAR_ARCHIVE);
@ -204,6 +207,7 @@ CVAR (Color, am_ovthingcolor_friend, 0xe88800, CVAR_ARCHIVE);
CVAR (Color, am_ovthingcolor_monster, 0xe88800, CVAR_ARCHIVE);
CVAR (Color, am_ovthingcolor_item, 0xe88800, CVAR_ARCHIVE);
CVAR (Color, am_ovthingcolor_citem, 0xe88800, CVAR_ARCHIVE);
CVAR (Int, am_showthingsprites, 0, CVAR_ARCHIVE);
static int bigstate = 0;
@ -412,6 +416,9 @@ static bool stopped = true;
static void AM_calcMinMaxMtoF();
static void DrawMarker (FTexture *tex, fixed_t x, fixed_t y, int yadjust,
INTBOOL flip, fixed_t xscale, fixed_t yscale, int translation, fixed_t alpha, DWORD fillcolor, FRenderStyle renderstyle);
void AM_rotatePoint (fixed_t *x, fixed_t *y);
void AM_rotate (fixed_t *x, fixed_t *y, angle_t an);
void AM_doFollowPlayer ();
@ -917,7 +924,9 @@ static void AM_initColors (bool overlayed)
ThingColor_Monster.FromCVar (am_ovthingcolor_monster);
ThingColor.FromCVar (am_ovthingcolor);
LockedColor.FromCVar (am_ovotherwallscolor);
EFWallColor = FDWallColor = CDWallColor = LockedColor;
EFWallColor.FromCVar (am_ovefwallcolor);
FDWallColor.FromCVar (am_ovfdwallcolor);
CDWallColor.FromCVar (am_ovcdwallcolor);
TSWallColor.FromCVar (am_ovunseencolor);
NotSeenColor = TSWallColor;
InterTeleportColor.FromCVar (am_ovtelecolor);
@ -2193,6 +2202,12 @@ AM_drawLineCharacter
void AM_drawPlayers ()
{
if (am_cheat >= 2 && am_showthingsprites > 0)
{
// Player sprites are drawn with the others
return;
}
mpoint_t pt;
angle_t angle;
int i;
@ -2328,7 +2343,6 @@ void AM_drawKeys ()
//
//
//=============================================================================
void AM_drawThings ()
{
AMColor color;
@ -2342,75 +2356,116 @@ void AM_drawThings ()
t = sectors[i].thinglist;
while (t)
{
p.x = t->x >> FRACTOMAPBITS;
p.y = t->y >> FRACTOMAPBITS;
angle = t->angle;
if (am_rotate == 1 || (am_rotate == 2 && viewactive))
if (am_cheat > 0 || !(t->flags6 & MF6_NOTONAUTOMAP))
{
AM_rotatePoint (&p.x, &p.y);
angle += ANG90 - players[consoleplayer].camera->angle;
}
p.x = t->x >> FRACTOMAPBITS;
p.y = t->y >> FRACTOMAPBITS;
color = ThingColor;
// use separate colors for special thing types
if (t->flags3&MF3_ISMONSTER && !(t->flags&MF_CORPSE))
{
if (t->flags & MF_FRIENDLY || !(t->flags & MF_COUNTKILL)) color = ThingColor_Friend;
else color = ThingColor_Monster;
}
else if (t->flags&MF_SPECIAL)
{
// Find the key's own color.
// Only works correctly if single-key locks have lower numbers than any-key locks.
// That is the case for all default keys, however.
if (t->IsKindOf(RUNTIME_CLASS(AKey)))
if (am_showthingsprites > 0 && t->sprite > 0)
{
if (G_SkillProperty(SKILLP_EasyKey))
{
// Already drawn by AM_drawKeys(), so don't draw again
color.Index = -1;
}
else if (am_showkeys)
{
int P_GetMapColorForKey (AInventory * key);
int c = P_GetMapColorForKey(static_cast<AKey *>(t));
FTexture *texture = NULL;
spriteframe_t *frame;
angle_t rotation = 0;
if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c));
else color = ThingColor_CountItem;
AM_drawLineCharacter(&CheatKey[0], CheatKey.Size(), 0, 0, color, p.x, p.y);
color.Index = -1;
}
else
// try all modes backwards until a valid texture has been found.
for(int show = am_showthingsprites; show > 0 && texture == NULL; show--)
{
color = ThingColor_Item;
const spritedef_t& sprite = sprites[t->sprite];
const size_t spriteIndex = sprite.spriteframes + (show > 1 ? t->frame : 0);
frame = &SpriteFrames[spriteIndex];
angle_t angle = ANGLE_270 - t->angle;
if (frame->Texture[0] != frame->Texture[1]) angle += (ANGLE_180 / 16);
if (am_rotate == 1 || (am_rotate == 2 && viewactive))
{
angle += players[consoleplayer].camera->angle - ANGLE_90;
}
rotation = angle >> 28;
const FTextureID textureID = frame->Texture[show > 2 ? rotation : 0];
texture = TexMan(textureID);
}
if (texture == NULL) goto drawTriangle; // fall back to standard display if no sprite can be found.
const fixed_t spriteXScale = FixedMul(t->scaleX, 10 * scale_mtof);
const fixed_t spriteYScale = FixedMul(t->scaleY, 10 * scale_mtof);
DrawMarker (texture, p.x, p.y, 0, !!(frame->Flip & (1 << rotation)),
spriteXScale, spriteYScale, t->Translation, FRACUNIT, 0, LegacyRenderStyles[STYLE_Normal]);
}
else
{
drawTriangle:
angle = t->angle;
if (am_rotate == 1 || (am_rotate == 2 && viewactive))
{
AM_rotatePoint (&p.x, &p.y);
angle += ANG90 - players[consoleplayer].camera->angle;
}
color = ThingColor;
// use separate colors for special thing types
if (t->flags3&MF3_ISMONSTER && !(t->flags&MF_CORPSE))
{
if (t->flags & MF_FRIENDLY || !(t->flags & MF_COUNTKILL)) color = ThingColor_Friend;
else color = ThingColor_Monster;
}
else if (t->flags&MF_SPECIAL)
{
// Find the key's own color.
// Only works correctly if single-key locks have lower numbers than any-key locks.
// That is the case for all default keys, however.
if (t->IsKindOf(RUNTIME_CLASS(AKey)))
{
if (G_SkillProperty(SKILLP_EasyKey))
{
// Already drawn by AM_drawKeys(), so don't draw again
color.Index = -1;
}
else if (am_showkeys)
{
int P_GetMapColorForKey (AInventory * key);
int c = P_GetMapColorForKey(static_cast<AKey *>(t));
if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c));
else color = ThingColor_CountItem;
AM_drawLineCharacter(&CheatKey[0], CheatKey.Size(), 0, 0, color, p.x, p.y);
color.Index = -1;
}
else
{
color = ThingColor_Item;
}
}
else if (t->flags&MF_COUNTITEM)
color = ThingColor_CountItem;
else
color = ThingColor_Item;
}
if (color.Index != -1)
{
AM_drawLineCharacter
(thintriangle_guy, NUMTHINTRIANGLEGUYLINES,
16<<MAPBITS, angle, color, p.x, p.y);
}
if (am_cheat >= 3)
{
static const mline_t box[4] =
{
{ { -MAPUNIT, -MAPUNIT }, { MAPUNIT, -MAPUNIT } },
{ { MAPUNIT, -MAPUNIT }, { MAPUNIT, MAPUNIT } },
{ { MAPUNIT, MAPUNIT }, { -MAPUNIT, MAPUNIT } },
{ { -MAPUNIT, MAPUNIT }, { -MAPUNIT, -MAPUNIT } },
};
AM_drawLineCharacter (box, 4, t->radius >> FRACTOMAPBITS, angle - t->angle, color, p.x, p.y);
}
}
else if (t->flags&MF_COUNTITEM)
color = ThingColor_CountItem;
else
color = ThingColor_Item;
}
if (color.Index != -1)
{
AM_drawLineCharacter
(thintriangle_guy, NUMTHINTRIANGLEGUYLINES,
16<<MAPBITS, angle, color, p.x, p.y);
}
if (am_cheat >= 3)
{
static const mline_t box[4] =
{
{ { -MAPUNIT, -MAPUNIT }, { MAPUNIT, -MAPUNIT } },
{ { MAPUNIT, -MAPUNIT }, { MAPUNIT, MAPUNIT } },
{ { MAPUNIT, MAPUNIT }, { -MAPUNIT, MAPUNIT } },
{ { -MAPUNIT, MAPUNIT }, { -MAPUNIT, -MAPUNIT } },
};
AM_drawLineCharacter (box, 4, t->radius >> FRACTOMAPBITS, angle - t->angle, color, p.x, p.y);
}
t = t->snext;
}

View File

@ -51,6 +51,7 @@
#include "i_system.h"
#include "doomerrors.h"
#include "doomstat.h"
#include "gstrings.h"
#include "s_sound.h"
@ -343,22 +344,30 @@ CCMD (changemap)
if (argv.argc() > 1)
{
if (!P_CheckMapData(argv[1]))
try
{
Printf ("No map %s\n", argv[1]);
}
else
{
if (argv.argc() > 2)
if (!P_CheckMapData(argv[1]))
{
Net_WriteByte (DEM_CHANGEMAP2);
Net_WriteByte (atoi(argv[2]));
Printf ("No map %s\n", argv[1]);
}
else
{
Net_WriteByte (DEM_CHANGEMAP);
if (argv.argc() > 2)
{
Net_WriteByte (DEM_CHANGEMAP2);
Net_WriteByte (atoi(argv[2]));
}
else
{
Net_WriteByte (DEM_CHANGEMAP);
}
Net_WriteString (argv[1]);
}
Net_WriteString (argv[1]);
}
catch(CRecoverableError &error)
{
if (error.GetMessage())
Printf("%s", error.GetMessage());
}
}
else
@ -960,8 +969,8 @@ CCMD(nextmap)
{
if (netgame)
{
Printf ("Use "TEXTCOLOR_BOLD"changemap"TEXTCOLOR_NORMAL" instead. "TEXTCOLOR_BOLD"Nextmap"
TEXTCOLOR_NORMAL" is for single-player only.\n");
Printf ("Use " TEXTCOLOR_BOLD "changemap" TEXTCOLOR_NORMAL " instead. " TEXTCOLOR_BOLD "Nextmap"
TEXTCOLOR_NORMAL " is for single-player only.\n");
return;
}
char *next = NULL;
@ -988,8 +997,8 @@ CCMD(nextsecret)
{
if (netgame)
{
Printf ("Use "TEXTCOLOR_BOLD"changemap"TEXTCOLOR_NORMAL" instead. "TEXTCOLOR_BOLD"Nextsecret"
TEXTCOLOR_NORMAL" is for single-player only.\n");
Printf ("Use " TEXTCOLOR_BOLD "changemap" TEXTCOLOR_NORMAL " instead. " TEXTCOLOR_BOLD "Nextsecret"
TEXTCOLOR_NORMAL " is for single-player only.\n");
return;
}
char *next = NULL;
@ -1138,4 +1147,4 @@ CCMD(secret)
else inlevel = false;
}
}
}
}

View File

@ -2121,7 +2121,20 @@ static bool C_TabCompleteList ()
Printf (TEXTCOLOR_BLUE "Completions for %s:\n", CmdLine+2);
for (i = TabPos; nummatches > 0; ++i, --nummatches)
{
Printf ("%-*s", int(maxwidth), TabCommands[i].TabName.GetChars());
// [Dusk] Print console commands blue, CVars green, aliases red.
const char* colorcode = "";
FConsoleCommand* ccmd;
if (FindCVar (TabCommands[i].TabName, NULL))
colorcode = TEXTCOLOR_GREEN;
else if ((ccmd = FConsoleCommand::FindByName (TabCommands[i].TabName)) != NULL)
{
if (ccmd->IsAlias())
colorcode = TEXTCOLOR_RED;
else
colorcode = TEXTCOLOR_LIGHTBLUE;
}
Printf ("%s%-*s", colorcode, int(maxwidth), TabCommands[i].TabName.GetChars());
x += maxwidth;
if (x > ConCols - maxwidth)
{

View File

@ -92,8 +92,8 @@ private:
struct FActionMap
{
unsigned int Key; // value from passing Name to MakeKey()
FButtonStatus *Button;
unsigned int Key; // value from passing Name to MakeKey()
char Name[12];
};
@ -134,38 +134,38 @@ bool ParsingKeyConf;
FActionMap ActionMaps[] =
{
{ 0x0d52d67b, &Button_AM_PanLeft, "am_panleft"},
{ 0x125f5226, &Button_User2, "user2" },
{ 0x1eefa611, &Button_Jump, "jump" },
{ 0x201f1c55, &Button_Right, "right" },
{ 0x20ccc4d5, &Button_Zoom, "zoom" },
{ 0x23a99cd7, &Button_Back, "back" },
{ 0x41df90c2, &Button_AM_ZoomIn, "am_zoomin"},
{ 0x426b69e7, &Button_Reload, "reload" },
{ 0x4463f43a, &Button_LookDown, "lookdown" },
{ 0x51f7a334, &Button_AM_ZoomOut, "am_zoomout"},
{ 0x534c30ee, &Button_User4, "user4" },
{ 0x5622bf42, &Button_Attack, "attack" },
{ 0x577712d0, &Button_User1, "user1" },
{ 0x57c25cb2, &Button_Klook, "klook" },
{ 0x59f3e907, &Button_Forward, "forward" },
{ 0x6167ce99, &Button_MoveDown, "movedown" },
{ 0x676885b8, &Button_AltAttack, "altattack" },
{ 0x6fa41b84, &Button_MoveLeft, "moveleft" },
{ 0x818f08e6, &Button_MoveRight, "moveright" },
{ 0x8197097b, &Button_AM_PanRight, "am_panright"},
{ 0x8d89955e, &Button_AM_PanUp, "am_panup"} ,
{ 0xa2b62d8b, &Button_Mlook, "mlook" },
{ 0xab2c3e71, &Button_Crouch, "crouch" },
{ 0xb000b483, &Button_Left, "left" },
{ 0xb62b1e49, &Button_LookUp, "lookup" },
{ 0xb6f8fe92, &Button_User3, "user3" },
{ 0xb7e6a54b, &Button_Strafe, "strafe" },
{ 0xce301c81, &Button_AM_PanDown, "am_pandown"},
{ 0xd5897c73, &Button_ShowScores, "showscores" },
{ 0xe0ccb317, &Button_Speed, "speed" },
{ 0xe0cfc260, &Button_Use, "use" },
{ 0xfdd701c7, &Button_MoveUp, "moveup" },
{ &Button_AM_PanLeft, 0x0d52d67b, "am_panleft"},
{ &Button_User2, 0x125f5226, "user2" },
{ &Button_Jump, 0x1eefa611, "jump" },
{ &Button_Right, 0x201f1c55, "right" },
{ &Button_Zoom, 0x20ccc4d5, "zoom" },
{ &Button_Back, 0x23a99cd7, "back" },
{ &Button_AM_ZoomIn, 0x41df90c2, "am_zoomin"},
{ &Button_Reload, 0x426b69e7, "reload" },
{ &Button_LookDown, 0x4463f43a, "lookdown" },
{ &Button_AM_ZoomOut, 0x51f7a334, "am_zoomout"},
{ &Button_User4, 0x534c30ee, "user4" },
{ &Button_Attack, 0x5622bf42, "attack" },
{ &Button_User1, 0x577712d0, "user1" },
{ &Button_Klook, 0x57c25cb2, "klook" },
{ &Button_Forward, 0x59f3e907, "forward" },
{ &Button_MoveDown, 0x6167ce99, "movedown" },
{ &Button_AltAttack, 0x676885b8, "altattack" },
{ &Button_MoveLeft, 0x6fa41b84, "moveleft" },
{ &Button_MoveRight, 0x818f08e6, "moveright" },
{ &Button_AM_PanRight, 0x8197097b, "am_panright"},
{ &Button_AM_PanUp, 0x8d89955e, "am_panup"} ,
{ &Button_Mlook, 0xa2b62d8b, "mlook" },
{ &Button_Crouch, 0xab2c3e71, "crouch" },
{ &Button_Left, 0xb000b483, "left" },
{ &Button_LookUp, 0xb62b1e49, "lookup" },
{ &Button_User3, 0xb6f8fe92, "user3" },
{ &Button_Strafe, 0xb7e6a54b, "strafe" },
{ &Button_AM_PanDown, 0xce301c81, "am_pandown"},
{ &Button_ShowScores, 0xd5897c73, "showscores" },
{ &Button_Speed, 0xe0ccb317, "speed" },
{ &Button_Use, 0xe0cfc260, "use" },
{ &Button_MoveUp, 0xfdd701c7, "moveup" },
};
#define NUM_ACTIONS countof(ActionMaps)
@ -627,7 +627,14 @@ void C_DoCommand (const char *cmd, int keynum)
}
else
{
new DStoredCommand (com, beg);
if (len == 4 && strnicmp(beg, "warp", 4) == 0)
{
StoredWarp = beg;
}
else
{
new DStoredCommand (com, beg);
}
}
}
else
@ -955,6 +962,11 @@ bool FConsoleCommand::AddToHash (FConsoleCommand **table)
return true;
}
FConsoleCommand* FConsoleCommand::FindByName (const char* name)
{
return FindNameInHashTable (Commands, name, strlen (name));
}
FConsoleCommand::FConsoleCommand (const char *name, CCmdRun runFunc)
: m_RunFunc (runFunc)
{

View File

@ -93,6 +93,7 @@ public:
void PrintCommand () { Printf ("%s\n", m_Name); }
virtual void Run (FCommandLine &args, APlayerPawn *instigator, int key);
static FConsoleCommand* FindByName (const char* name);
FConsoleCommand *m_Next, **m_Prev;
char *m_Name;

View File

@ -105,6 +105,7 @@ static FCompatOption Options[] =
{ "vileghosts", BCOMPATF_VILEGHOSTS, SLOT_BCOMPAT },
{ "ignoreteleporttags", BCOMPATF_BADTELEPORTERS, SLOT_BCOMPAT },
{ "rebuildnodes", BCOMPATF_REBUILDNODES, SLOT_BCOMPAT },
{ "linkfrozenprops", BCOMPATF_LINKFROZENPROPS, SLOT_BCOMPAT },
// list copied from g_mapinfo.cpp
{ "shorttex", COMPATF_SHORTTEX, SLOT_COMPAT },
@ -540,7 +541,7 @@ CCMD (mapchecksum)
}
for (int i = 1; i < argv.argc(); ++i)
{
map = P_OpenMapData(argv[i]);
map = P_OpenMapData(argv[i], true);
if (map == NULL)
{
Printf("Cannot load %s as a map\n", argv[i]);

View File

@ -2338,6 +2338,7 @@ int D_LoadDehLumps()
count += D_LoadDehLump(lumpnum);
}
#if 0 // commented out for 'maint' version.
if (0 == PatchSize)
{
// No DEH/BEX patch is loaded yet, try to find lump(s) with specific extensions
@ -2358,6 +2359,7 @@ int D_LoadDehLumps()
}
}
}
#endif
return count;
}

View File

@ -367,7 +367,7 @@ int FIWadManager::CheckIWAD (const char *doomwaddir, WadStuff *wads)
// Under UNIX OSes, the search path is:
// 1. Current directory
// 2. $DOOMWADDIR
// 3. $HOME/.zdoom
// 3. $HOME/.config/zdoom
// 4. The share directory defined at compile time (/usr/local/share/zdoom)
//
// The search path can be altered by editing the IWADSearch.Directories
@ -516,9 +516,19 @@ int FIWadManager::IdentifyVersion (TArray<FString> &wadfiles, const char *iwad,
I_FatalError ("Cannot find a game IWAD (doom.wad, doom2.wad, heretic.wad, etc.).\n"
"Did you install ZDoom properly? You can do either of the following:\n"
"\n"
#if defined(_WIN32)
"1. Place one or more of these wads in the same directory as ZDoom.\n"
"2. Edit your zdoom-username.ini and add the directories of your iwads\n"
"to the list beneath [IWADSearch.Directories]");
#elif defined(__APPLE__)
"1. Place one or more of these wads in ~/Library/Application Support/zdoom/\n"
"2. Edit your ~/Library/Preferences/zdoom.ini and add the directories\n"
"of your iwads to the list beneath [IWADSearch.Directories]");
#else
"1. Place one or more of these wads in ~/.config/zdoom/.\n"
"2. Edit your ~/.config/zdoom/zdoom.ini and add the directories of your\n"
"iwads to the list beneath [IWADSearch.Directories]");
#endif
}
pickwad = 0;

View File

@ -218,6 +218,7 @@ int NoWipe; // [RH] Allow wipe? (Needs to be set each time)
bool singletics = false; // debug flag to cancel adaptiveness
FString startmap;
bool autostart;
FString StoredWarp;
bool advancedemo;
FILE *debugfile;
event_t events[MAXEVENTS];
@ -1300,7 +1301,7 @@ void D_DoAdvanceDemo (void)
gamestate = GS_DEMOSCREEN;
pagename = gameinfo.titlePage;
pagetic = (int)(gameinfo.titleTime * TICRATE);
S_StartMusic (gameinfo.titleMusic);
S_ChangeMusic (gameinfo.titleMusic, gameinfo.titleOrder, false);
demosequence = 3;
pagecount = 0;
C_HideConsole ();
@ -2081,7 +2082,7 @@ static void CheckCmdLine()
{
startmap = "&wt@01";
}
autostart = false;
autostart = StoredWarp.IsNotEmpty();
const char *val = Args->CheckValue ("-skill");
if (val)
@ -2281,8 +2282,6 @@ void D_DoomMain (void)
execFiles = Args->GatherFiles ("-exec");
D_MultiExec (execFiles, true);
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
CopyFiles(allwads, pwads);
// Since this function will never leave we must delete this array here manually.
@ -2298,6 +2297,8 @@ void D_DoomMain (void)
// Now that wads are loaded, define mod-specific cvars.
ParseCVarInfo();
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
// [RH] Initialize localizable strings.
GStrings.LoadStrings (false);
@ -2529,6 +2530,11 @@ void D_DoomMain (void)
if (demorecording)
G_BeginRecording (startmap);
G_InitNew (startmap, false);
if (StoredWarp.IsNotEmpty())
{
AddCommandString(StoredWarp.LockBuffer());
StoredWarp = NULL;
}
}
else
{

View File

@ -713,7 +713,7 @@ void D_WriteUserInfoStrings (int pnum, BYTE **stream, bool compact)
if (!compact)
{ // In verbose mode, prepend the cvar's name
*stream += sprintf(*((char **)stream), "\\%s\\", pair->Key.GetChars());
*stream += sprintf(*((char **)stream), "\\%s", pair->Key.GetChars());
}
// A few of these need special handling for compatibility reasons.
switch (pair->Key.GetIndex())
@ -1048,3 +1048,15 @@ CCMD (playerinfo)
}
}
}
userinfo_t::~userinfo_t()
{
TMapIterator<FName, FBaseCVar *> it(*this);
TMap<FName, FBaseCVar *>::Pair *pair;
while (it.NextPair(pair))
{
delete pair->Value;
}
this->Clear();
}

View File

@ -140,6 +140,8 @@ public:
int SpawnMask;
FNameNoInit MorphWeapon;
fixed_t AttackZOffset; // attack height, relative to player center
fixed_t UseRange; // [NS] Distance at which player can +use
fixed_t AirCapacity; // Multiplier for air supply underwater.
const PClass *FlechetteType;
// [CW] Fades for when you are being damaged.
@ -260,6 +262,8 @@ enum
struct userinfo_t : TMap<FName,FBaseCVar *>
{
~userinfo_t();
int GetAimDist() const
{
if (dmflags2 & DF2_NOAUTOAIM)
@ -321,6 +325,10 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
{
return *static_cast<FIntCVar *>(*CheckKey(NAME_Gender));
}
bool GetNoAutostartMap() const
{
return *static_cast<FBoolCVar *>(*CheckKey(NAME_Wi_NoAutostartMap));
}
void Reset();
int TeamChanged(int team);
@ -344,6 +352,7 @@ class player_t
{
public:
player_t();
player_t &operator= (const player_t &p);
void Serialize (FArchive &arc);
size_t FixPointers (const DObject *obj, DObject *replacement);

View File

@ -153,6 +153,7 @@ enum ELineFlags
ML_BLOCKPROJECTILE = 0x01000000,
ML_BLOCKUSE = 0x02000000, // blocks all use actions through this line
ML_BLOCKSIGHT = 0x04000000, // blocks monster line of sight
ML_BLOCKHITSCAN = 0x08000000, // blocks hitscan attacks
};
@ -342,6 +343,7 @@ struct FMapThing
int special;
int args[5];
int Conversation;
fixed_t gravity;
void Serialize (FArchive &);
};

View File

@ -349,6 +349,7 @@ enum
BCOMPATF_BADTELEPORTERS = 1 << 3, // Ignore tags on Teleport specials
BCOMPATF_BADPORTALS = 1 << 4, // Restores the old unstable portal behavior
BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild
BCOMPATF_LINKFROZENPROPS = 1 << 6, // Clearing PROP_TOTALLYFROZEN or PROP_FROZEN also clears the other
};
// phares 3/20/98:

View File

@ -59,6 +59,8 @@ extern FString startmap; // [RH] Actual map name now
extern bool autostart;
extern FString StoredWarp; // [RH] +warp at the command line
// Selected by user.
EXTERN_CVAR (Int, gameskill);
extern int NextSkill; // [RH] Skill to use at next level load

View File

@ -357,12 +357,10 @@ void DThinker::DestroyThinkersInList (FThinkerList &list)
{
if (list.Sentinel != NULL)
{
DThinker *node = list.Sentinel->NextThinker;
while (node != list.Sentinel)
for (DThinker *node = list.Sentinel->NextThinker; node != list.Sentinel; node = list.Sentinel->NextThinker)
{
DThinker *next = node->NextThinker;
assert(node != NULL);
node->Destroy();
node = next;
}
list.Sentinel->Destroy();
list.Sentinel = NULL;
@ -380,9 +378,8 @@ void DThinker::DestroyMostThinkersInList (FThinkerList &list, int stat)
// it from the list. G_FinishTravel() will find it later from
// a players[].mo link and destroy it then, after copying various
// information to a new player.
for (DThinker *probe = list.Sentinel->NextThinker, *next; probe != list.Sentinel; probe = next)
for (DThinker *probe = list.Sentinel->NextThinker; probe != list.Sentinel; probe = list.Sentinel->NextThinker)
{
next = probe->NextThinker;
if (!probe->IsKindOf(RUNTIME_CLASS(APlayerPawn)) || // <- should not happen
static_cast<AActor *>(probe)->player == NULL ||
static_cast<AActor *>(probe)->player->mo != probe)

View File

@ -101,15 +101,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget)
//
// A_VileAttack
//
// A_VileAttack flags
#define VAF_DMGTYPEAPPLYTODIRECT 1
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
{
ACTION_PARAM_START(6);
ACTION_PARAM_START(7);
ACTION_PARAM_SOUND(snd,0);
ACTION_PARAM_INT(dmg,1);
ACTION_PARAM_INT(blastdmg,2);
ACTION_PARAM_INT(blastrad,3);
ACTION_PARAM_FIXED(thrust,4);
ACTION_PARAM_NAME(dmgtype,5);
ACTION_PARAM_INT(flags,6);
AActor *fire, *target;
angle_t an;
@ -123,7 +128,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
return;
S_Sound (self, CHAN_WEAPON, snd, 1, ATTN_NORM);
int newdam = P_DamageMobj (target, self, self, dmg, NAME_None);
int newdam;
if (flags & VAF_DMGTYPEAPPLYTODIRECT)
newdam = P_DamageMobj (target, self, self, dmg, dmgtype);
else
newdam = P_DamageMobj (target, self, self, dmg, NAME_None);
P_TraceBleed (newdam > 0 ? newdam : dmg, target);
an = self->angle >> ANGLETOFINESHIFT;

View File

@ -53,7 +53,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch)
angle += pr_punch.Random2() << 18;
pitch = P_AimLineAttack (self, angle, MELEERANGE, &linetarget);
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &linetarget);
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, LAF_ISMELEEATTACK, &linetarget);
// turn to face target
if (linetarget)
@ -589,7 +589,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
damage += (pr_bfgspray() & 7) + 1;
thingToHit = linetarget;
int newdam = P_DamageMobj (thingToHit, self->target, self->target, damage, spray != NULL? FName(spray->DamageType) : FName(NAME_BFGSplash));
int newdam = P_DamageMobj (thingToHit, self->target, self->target, damage, spray != NULL? FName(spray->DamageType) : FName(NAME_BFGSplash),
spray != NULL && (spray->flags3 & MF3_FOILINVUL)? DMG_FOILINVUL : 0);
P_TraceBleed (newdam > 0 ? newdam : damage, thingToHit, self->target);
}
}

View File

@ -862,7 +862,10 @@ static void ChangeSpy (int changespy)
int pnum = consoleplayer;
if (changespy != SPY_CANCEL)
{
pnum = int(players[consoleplayer].camera->player - players);
player_t *player = players[consoleplayer].camera->player;
// only use the camera as starting index if it's a valid player.
if (player != NULL) pnum = int(players[consoleplayer].camera->player - players);
int step = (changespy == SPY_NEXT) ? 1 : -1;
do

View File

@ -58,12 +58,12 @@ class AFSwordMissile : public AActor
{
DECLARE_CLASS (AFSwordMissile, AActor)
public:
int DoSpecialDamage(AActor *victim, AActor *source, int damage, FName damagetype);
int DoSpecialDamage(AActor *victim, int damage, FName damagetype);
};
IMPLEMENT_CLASS (AFSwordMissile)
int AFSwordMissile::DoSpecialDamage(AActor *victim, AActor *source, int damage, FName damagetype)
int AFSwordMissile::DoSpecialDamage(AActor *victim, int damage, FName damagetype)
{
if (victim->player)
{

View File

@ -40,6 +40,7 @@
#include "s_sound.h"
#include "d_event.h"
#include "m_random.h"
#include "doomerrors.h"
#include "doomstat.h"
#include "wi_stuff.h"
#include "w_wad.h"
@ -164,19 +165,27 @@ CCMD (map)
{
if (netgame)
{
Printf ("Use "TEXTCOLOR_BOLD"changemap"TEXTCOLOR_NORMAL" instead. "TEXTCOLOR_BOLD"Map"
TEXTCOLOR_NORMAL" is for single-player only.\n");
Printf ("Use " TEXTCOLOR_BOLD "changemap" TEXTCOLOR_NORMAL " instead. " TEXTCOLOR_BOLD "Map"
TEXTCOLOR_NORMAL " is for single-player only.\n");
return;
}
if (argv.argc() > 1)
{
if (!P_CheckMapData(argv[1]))
try
{
Printf ("No map %s\n", argv[1]);
if (!P_CheckMapData(argv[1]))
{
Printf ("No map %s\n", argv[1]);
}
else
{
G_DeferedInitNew (argv[1]);
}
}
else
catch(CRecoverableError &error)
{
G_DeferedInitNew (argv[1]);
if (error.GetMessage())
Printf("%s", error.GetMessage());
}
}
else
@ -1914,7 +1923,7 @@ CCMD(listmaps)
for(unsigned i = 0; i < wadlevelinfos.Size(); i++)
{
level_info_t *info = &wadlevelinfos[i];
MapData *map = P_OpenMapData(info->mapname);
MapData *map = P_OpenMapData(info->mapname, true);
if (map != NULL)
{

View File

@ -589,7 +589,7 @@ void APowerInvisibility::DoEffect ()
Super::DoEffect();
// Due to potential interference with other PowerInvisibility items
// the effect has to be refreshed each tic.
fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT;
fixed_t ts = (Strength/100) * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT;
Owner->alpha = clamp<fixed_t>((OPAQUE - ts), 0, OPAQUE);
switch (Mode)
{
@ -669,7 +669,7 @@ int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis)
else if (changed == 1)
{
// something else set the weapon sprite back to opaque but this item is still active.
fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT;
fixed_t ts = (Strength/100) * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT;
vis->alpha = clamp<fixed_t>((OPAQUE - ts), 0, OPAQUE);
switch (Mode)
{
@ -696,7 +696,7 @@ int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis)
// Handling of Strife-like cumulative invisibility powerups, the weapon itself shouldn't become invisible
if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0))
{
vis->alpha = clamp<fixed_t>((OPAQUE - Strength), 0, OPAQUE);
vis->alpha = clamp<fixed_t>((OPAQUE - (Strength/100)), 0, OPAQUE);
vis->colormap = SpecialColormaps[INVERSECOLORMAP].Colormap;
}
return -1; // This item is valid so another one shouldn't reset the translucency
@ -1697,7 +1697,7 @@ void APowerRegeneration::DoEffect()
{
if (Owner != NULL && Owner->health > 0 && (level.time & 31) == 0)
{
if (P_GiveBody(Owner, 5))
if (P_GiveBody(Owner, Strength/FRACUNIT))
{
S_Sound(Owner, CHAN_ITEM, "*regenerate", 1, ATTN_NORM );
}

View File

@ -38,6 +38,7 @@ class ACustomBridge : public AActor
DECLARE_CLASS (ACustomBridge, AActor)
public:
void BeginPlay ();
void Destroy();
};
IMPLEMENT_CLASS(ACustomBridge)
@ -58,6 +59,25 @@ void ACustomBridge::BeginPlay ()
}
}
void ACustomBridge::Destroy()
{
// Hexen originally just set a flag to make the bridge balls remove themselves in A_BridgeOrbit.
// But this is not safe with custom bridge balls that do not necessarily call that function.
// So the best course of action is to look for all bridge balls here and destroy them ourselves.
TThinkerIterator<AActor> it;
AActor *thing;
while ((thing = it.Next()))
{
if (thing->target == this)
{
thing->Destroy();
}
}
Super::Destroy();
}
// Action functions for the non-Doom bridge --------------------------------
#define ORBIT_RADIUS 15
@ -89,10 +109,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_BridgeOrbit)
// Set rotation radius
if (self->target->args[4]) rotationradius = ((self->target->args[4] * self->target->radius) / (100 * FRACUNIT));
if (self->target->special1)
{
self->SetState (NULL);
}
self->angle += rotationspeed;
self->x = self->target->x + rotationradius * finecosine[self->angle >> ANGLETOFINESHIFT];
self->y = self->target->y + rotationradius * finesine[self->angle >> ANGLETOFINESHIFT];
@ -115,7 +131,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit)
cy = self->y;
cz = self->z;
startangle = pr_orbit() << 24;
self->special1 = 0;
// Spawn triad into world -- may be more than a triad now.
int ballcount = self->args[2]==0 ? 3 : self->args[2];
@ -129,14 +144,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit)
}
}
/* never used
void A_BridgeRemove (AActor *self)
{
self->special1 = true; // Removing the bridge
self->flags &= ~MF_SOLID;
self->SetState (&ABridge::States[S_FREE_BRIDGE]);
}
*/
// Invisible bridge --------------------------------------------------------

View File

@ -785,7 +785,7 @@ void AInventory::BecomePickup ()
LinkToWorld ();
P_FindFloorCeiling (this);
}
flags = GetDefault()->flags | MF_DROPPED;
flags = (GetDefault()->flags | MF_DROPPED) & ~MF_COUNTITEM;
renderflags &= ~RF_INVISIBLE;
SetState (SpawnState);
}
@ -1792,7 +1792,10 @@ bool ABackpackItem::HandlePickup (AInventory *item)
AInventory *ABackpackItem::CreateTossable ()
{
ABackpackItem *pack = static_cast<ABackpackItem *>(Super::CreateTossable());
pack->bDepleted = true;
if (pack != NULL)
{
pack->bDepleted = true;
}
return pack;
}

View File

@ -121,7 +121,11 @@ class ARandomSpawner : public AActor
AActor * newmobj = NULL;
bool boss = false;
Super::PostBeginPlay();
if (Species == NAME_None) { Destroy(); return; }
if (Species == NAME_None)
{
Destroy();
return;
}
const PClass * cls = PClass::FindClass(Species);
if (this->flags & MF_MISSILE && target && target->target) // Attempting to spawn a missile.
{
@ -142,8 +146,9 @@ class ARandomSpawner : public AActor
newmobj->args[4] = args[4];
newmobj->special1 = special1;
newmobj->special2 = special2;
newmobj->SpawnFlags = SpawnFlags;
newmobj->SpawnFlags = SpawnFlags & ~MTF_SECRET; // MTF_SECRET needs special treatment to avoid incrementing the secret counter twice. It had already been processed for the spawner itself.
newmobj->HandleSpawnFlags();
newmobj->SpawnFlags = SpawnFlags;
newmobj->tid = tid;
newmobj->AddToHash();
newmobj->velx = velx;

View File

@ -352,11 +352,8 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags)
SetState("grin", false);
return 0;
}
else if (CurrentState == NULL)
{
bEvilGrin = false;
}
}
bEvilGrin = false;
bool ouch = (!st_oldouch && FaceHealth - player->health > ST_MUCHPAIN) || (st_oldouch && player->health - FaceHealth > ST_MUCHPAIN);
if (player->damagecount &&

View File

@ -53,6 +53,7 @@
#include "d_player.h"
#include "farchive.h"
#include "a_hexenglobal.h"
#include "gstrings.h"
#include "../version.h"
@ -1375,8 +1376,8 @@ void DBaseStatusBar::Draw (EHudState state)
// Draw monster count
if (am_showmonsters)
{
mysnprintf (line, countof(line), "MONSTERS:" TEXTCOLOR_GREY " %d/%d",
level.killed_monsters, level.total_monsters);
mysnprintf (line, countof(line), "%s" TEXTCOLOR_GREY " %d/%d",
GStrings("AM_MONSTERS"), level.killed_monsters, level.total_monsters);
screen->DrawText (SmallFont, highlight, 8, y, line,
DTA_CleanNoMove, true, TAG_DONE);
y += height;
@ -1385,8 +1386,8 @@ void DBaseStatusBar::Draw (EHudState state)
// Draw secret count
if (am_showsecrets)
{
mysnprintf (line, countof(line), "SECRETS:" TEXTCOLOR_GREY " %d/%d",
level.found_secrets, level.total_secrets);
mysnprintf (line, countof(line), "%s" TEXTCOLOR_GREY " %d/%d",
GStrings("AM_SECRETS"), level.found_secrets, level.total_secrets);
screen->DrawText (SmallFont, highlight, 8, y, line,
DTA_CleanNoMove, true, TAG_DONE);
y += height;
@ -1395,8 +1396,8 @@ void DBaseStatusBar::Draw (EHudState state)
// Draw item count
if (am_showitems)
{
mysnprintf (line, countof(line), "ITEMS:" TEXTCOLOR_GREY " %d/%d",
level.found_items, level.total_items);
mysnprintf (line, countof(line), "%s" TEXTCOLOR_GREY " %d/%d",
GStrings("AM_ITEMS"), level.found_items, level.total_items);
screen->DrawText (SmallFont, highlight, 8, y, line,
DTA_CleanNoMove, true, TAG_DONE);
}

View File

@ -184,6 +184,20 @@ const char* GameInfoBorders[] =
gameinfo.key.color = NAME_Null; \
}
#define GAMEINFOKEY_MUSIC(key, order, variable) \
else if(nextKey.CompareNoCase(variable) == 0) \
{ \
sc.MustGetToken(TK_StringConst); \
gameinfo.order = 0; \
char *colon = strchr (sc.String, ':'); \
if (colon) \
{ \
gameinfo.order = atoi(colon+1); \
*colon = 0; \
} \
gameinfo.key = sc.String; \
}
void FMapInfoParser::ParseGameInfo()
{
@ -286,12 +300,12 @@ void FMapInfoParser::ParseGameInfo()
GAMEINFOKEY_STRINGARRAY(creditPages, "CreditPage", 8, true)
GAMEINFOKEY_STRINGARRAY(PlayerClasses, "addplayerclasses", 0, false)
GAMEINFOKEY_STRINGARRAY(PlayerClasses, "playerclasses", 0, true)
GAMEINFOKEY_STRING(titleMusic, "titleMusic")
GAMEINFOKEY_MUSIC(titleMusic, titleOrder, "titleMusic")
GAMEINFOKEY_FLOAT(titleTime, "titleTime")
GAMEINFOKEY_FLOAT(advisoryTime, "advisoryTime")
GAMEINFOKEY_FLOAT(pageTime, "pageTime")
GAMEINFOKEY_STRING(chatSound, "chatSound")
GAMEINFOKEY_STRING(finaleMusic, "finaleMusic")
GAMEINFOKEY_MUSIC(finaleMusic, finaleOrder, "finaleMusic")
GAMEINFOKEY_CSTRING(finaleFlat, "finaleFlat", 8)
GAMEINFOKEY_STRINGARRAY(finalePages, "finalePage", 8, true)
GAMEINFOKEY_STRINGARRAY(infoPages, "addinfoPage", 8, false)
@ -309,7 +323,7 @@ void FMapInfoParser::ParseGameInfo()
GAMEINFOKEY_COLOR(defaultbloodparticlecolor, "defaultbloodparticlecolor")
GAMEINFOKEY_STRING(backpacktype, "backpacktype")
GAMEINFOKEY_STRING(statusbar, "statusbar")
GAMEINFOKEY_STRING(intermissionMusic, "intermissionMusic")
GAMEINFOKEY_MUSIC(intermissionMusic, intermissionOrder, "intermissionMusic")
GAMEINFOKEY_STRING(CursorPic, "CursorPic")
GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic")
GAMEINFOKEY_BOOL(drawreadthis, "drawreadthis")

View File

@ -91,11 +91,13 @@ struct gameinfo_t
TArray<FName> PlayerClasses;
FString titleMusic;
int titleOrder;
float titleTime;
float advisoryTime;
float pageTime;
FString chatSound;
FString finaleMusic;
int finaleOrder;
char finaleFlat[9];
char borderFlat[9];
char SkyFlatName[9];
@ -114,6 +116,7 @@ struct gameinfo_t
FString backpacktype;
FString statusbar;
FString intermissionMusic;
int intermissionOrder;
FString CursorPic;
DWORD dimcolor;
float dimamount;

View File

@ -42,11 +42,6 @@
extern FStringTable GStrings;
// QuitGame messages
#define NUM_QUITDOOMMESSAGES 14
#define NUM_QUITSTRIFEMESSAGES 8
#define NUM_QUITCHEXMESSAGES 7
extern const char *endmsg[];

View File

@ -80,7 +80,7 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first)
if (desc->mMusic.IsEmpty())
{
// only start the default music if this is the first action in an intermission
if (first) S_ChangeMusic (gameinfo.finaleMusic, 0, desc->mMusicLooping);
if (first) S_ChangeMusic (gameinfo.finaleMusic, gameinfo.finaleOrder, desc->mMusicLooping);
}
else
{

View File

@ -35,6 +35,7 @@
#include <string.h>
#include "m_argv.h"
#include "cmdlib.h"
#include "i_system.h"
IMPLEMENT_CLASS (DArgs)
@ -391,6 +392,14 @@ void DArgs::CollectFiles(const char *param, const char *extension)
}
}
// Optional: Replace short path names with long path names
#ifdef _WIN32
for (i = 0; i < work.Size(); ++i)
{
work[i] = I_GetLongPathName(work[i]);
}
#endif
// Step 3: Add work back to Argv, as long as it's non-empty.
if (work.Size() > 0)
{

View File

@ -12,7 +12,7 @@
#include <stdlib.h>
#include "doomtype.h"
#if defined(__GNUC__) && defined(__i386__)
#if defined(__GNUC__) && defined(__i386__) && !defined(__clang__)
#include "gccinlines.h"
#elif defined(_MSC_VER) && defined(_M_IX86)
#include "mscinlines.h"

View File

@ -131,7 +131,8 @@ void ClearSaveGames()
{
for(unsigned i=0;i<DLoadSaveMenu::SaveGames.Size(); i++)
{
delete DLoadSaveMenu::SaveGames[i];
if(!DLoadSaveMenu::SaveGames[i]->bNoDelete)
delete DLoadSaveMenu::SaveGames[i];
}
DLoadSaveMenu::SaveGames.Clear();
}
@ -898,7 +899,7 @@ IMPLEMENT_CLASS(DSaveMenu)
DSaveMenu::DSaveMenu(DMenu *parent, FListMenuDescriptor *desc)
: DLoadSaveMenu(parent, desc)
{
strcpy (NewSaveNode.Title, "<New Save Game>");
strcpy (NewSaveNode.Title, GStrings["NEWSAVE"]);
NewSaveNode.bNoDelete = true;
SaveGames.Insert(0, &NewSaveNode);
TopItem = 0;

View File

@ -166,15 +166,18 @@ public:
NewWidth = SCREENWIDTH;
NewHeight = SCREENHEIGHT;
}
OldWidth = SCREENWIDTH;
OldHeight = SCREENHEIGHT;
OldBits = DisplayBits;
NewBits = BitTranslate[DummyDepthCvar];
setmodeneeded = true;
testingmode = I_GetTime(false) + 5 * TICRATE;
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE);
SetModesMenu (NewWidth, NewHeight, NewBits);
return true;
else
{
OldWidth = SCREENWIDTH;
OldHeight = SCREENHEIGHT;
OldBits = DisplayBits;
NewBits = BitTranslate[DummyDepthCvar];
setmodeneeded = true;
testingmode = I_GetTime(false) + 5 * TICRATE;
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE);
SetModesMenu (NewWidth, NewHeight, NewBits);
return true;
}
}
return Super::Responder(ev);
}
@ -348,7 +351,7 @@ void M_InitVideoModesMenu ()
static bool GetSelectedSize (int *width, int *height)
{
FOptionMenuDescriptor *opt = GetVideoModeMenu();
if (opt != NULL)
if (opt != NULL && (unsigned)opt->mSelectedItem < opt->mItems.Size())
{
int line = opt->mSelectedItem;
int hsel;

View File

@ -442,6 +442,7 @@ xx(Alphafloor)
xx(Alphaceiling)
xx(Renderstylefloor)
xx(Renderstyleceiling)
xx(Waterzone)
xx(offsetx_top)
xx(offsety_top)
@ -464,6 +465,7 @@ xx(blockprojectiles)
xx(blockuse)
xx(hidden)
xx(blocksight)
xx(blockhitscan)
xx(Renderstyle)
@ -567,3 +569,4 @@ xx(NeverSwitchOnPickup)
xx(MoveBob)
xx(StillBob)
xx(PlayerClass)
xx(Wi_NoAutostartMap)

View File

@ -46,6 +46,7 @@
#include "p_acs.h"
#include "p_saveg.h"
#include "p_lnspec.h"
#include "p_enemy.h"
#include "m_random.h"
#include "doomstat.h"
#include "c_console.h"
@ -112,6 +113,9 @@ FRandom pr_acs ("ACS");
#define NOT_FLOOR 8
#define NOT_CEILING 16
// LineAtack flags
#define FHF_NORANDOMPUFFZ 1
// SpawnDecal flags
#define SDF_ABSANGLE 1
#define SDF_PERMANENT 2
@ -571,11 +575,7 @@ int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucke
}
else
{ // Scan for the next free entry
unsigned int i;
for (i = FirstFreeEntry + 1; i < Pool.Size() && Pool[i].Next != FREE_ENTRY; ++i)
{
}
FirstFreeEntry = i;
FindFirstFreeEntry(FirstFreeEntry + 1);
}
PoolEntry *entry = &Pool[index];
entry->Str = str;
@ -586,6 +586,23 @@ int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucke
return index | STRPOOL_LIBRARYID_OR;
}
//============================================================================
//
// ACSStringPool :: FindFirstFreeEntry
//
// Finds the first free entry, starting at base.
//
//============================================================================
void ACSStringPool::FindFirstFreeEntry(unsigned base)
{
while (base < Pool.Size() && Pool[base].Next != FREE_ENTRY)
{
base++;
}
FirstFreeEntry = base;
}
//============================================================================
//
// ACSStringPool :: ReadStrings
@ -634,6 +651,7 @@ void ACSStringPool::ReadStrings(PNGHandle *png, DWORD id)
{
delete[] str;
}
FindFirstFreeEntry(0);
}
}
@ -686,6 +704,7 @@ void ACSStringPool::Dump() const
Printf("%4u. (%2d) \"%s\"\n", i, Pool[i].LockCount, Pool[i].Str.GetChars());
}
}
Printf("First free %u\n", FirstFreeEntry);
}
//============================================================================
@ -3509,6 +3528,8 @@ enum
APROP_Radius = 36,
APROP_ReactionTime = 37,
APROP_MeleeRange = 38,
APROP_ViewHeight = 39,
APROP_AttackZOffset = 40
};
// These are needed for ACS's APROP_RenderStyle
@ -3724,6 +3745,16 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
actor->reactiontime = value;
break;
case APROP_ViewHeight:
if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
static_cast<APlayerPawn *>(actor)->ViewHeight = value;
break;
case APROP_AttackZOffset:
if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
static_cast<APlayerPawn *>(actor)->AttackZOffset = value;
break;
default:
// do nothing.
break;
@ -3796,6 +3827,23 @@ int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack,
case APROP_Radius: return actor->radius;
case APROP_ReactionTime:return actor->reactiontime;
case APROP_MeleeRange: return actor->meleerange;
case APROP_ViewHeight: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
{
return static_cast<APlayerPawn *>(actor)->ViewHeight;
}
else
{
return 0;
}
case APROP_AttackZOffset:
if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
{
return static_cast<APlayerPawn *>(actor)->AttackZOffset;
}
else
{
return 0;
}
case APROP_SeeSound: return GlobalACSStrings.AddString(actor->SeeSound, stack, stackdepth);
case APROP_AttackSound: return GlobalACSStrings.AddString(actor->AttackSound, stack, stackdepth);
@ -3848,6 +3896,8 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value)
case APROP_Radius:
case APROP_ReactionTime:
case APROP_MeleeRange:
case APROP_ViewHeight:
case APROP_AttackZOffset:
return (GetActorProperty(tid, property, NULL, 0) == value);
// Boolean values need to compare to a binary version of value
@ -4199,6 +4249,7 @@ enum EACSFunctions
ACSF_PlayActorSound,
ACSF_SpawnDecal,
ACSF_CheckFont,
ACSF_DropItem,
// ZDaemon
ACSF_GetTeamScore = 19620, // (int team)
@ -4966,10 +5017,13 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const
FName pufftype = argCount > 4 && args[4]? FName(FBehavior::StaticLookupString(args[4])) : NAME_BulletPuff;
FName damagetype = argCount > 5 && args[5]? FName(FBehavior::StaticLookupString(args[5])) : NAME_None;
fixed_t range = argCount > 6 && args[6]? args[6] : MISSILERANGE;
int flags = argCount > 7 && args[7]? args[7] : 0;
int fhflags = (flags & FHF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
if (args[0] == 0)
{
P_LineAttack(activator, angle, range, pitch, damage, damagetype, pufftype);
P_LineAttack(activator, angle, range, pitch, damage, damagetype, pufftype, fhflags);
}
else
{
@ -4978,7 +5032,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const
while ((source = it.Next()) != NULL)
{
P_LineAttack(activator, angle, range, pitch, damage, damagetype, pufftype);
P_LineAttack(activator, angle, range, pitch, damage, damagetype, pufftype, fhflags);
}
}
}
@ -5025,7 +5079,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
{
S_Sound(spot, chan, sid, vol, atten);
}
else if (!S_IsActorPlayingSomething(spot, chan, sid))
else if (!S_IsActorPlayingSomething(spot, chan & 7, sid))
{
S_Sound(spot, chan | CHAN_LOOP, sid, vol, atten);
}
@ -5198,6 +5252,39 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
// bool CheckFont(str fontname)
return V_GetFont(FBehavior::StaticLookupString(args[0])) != NULL;
case ACSF_DropItem:
{
const char *type = FBehavior::StaticLookupString(args[1]);
int amount = argCount >= 3? args[2] : -1;
int chance = argCount >= 4? args[3] : 256;
const PClass *cls = PClass::FindClass(type);
int cnt = 0;
if (cls != NULL)
{
if (args[0] == 0)
{
if (activator != NULL)
{
P_DropItem(activator, cls, amount, chance);
cnt++;
}
}
else
{
FActorIterator it(args[0]);
AActor *actor;
while ((actor = it.Next()) != NULL)
{
P_DropItem(actor, cls, amount, chance);
cnt++;
}
}
return cnt;
}
break;
}
default:
break;
}
@ -5556,7 +5643,8 @@ int DLevelScript::RunScript ()
case PCD_PUSHFUNCTION:
{
int funcnum = NEXTBYTE;
PushToStack(funcnum | activeBehavior->GetLibraryID());
// Not technically a string, but since we use the same tagging mechanism
PushToStack(TAGSTR(funcnum));
break;
}
case PCD_CALL:
@ -5572,7 +5660,7 @@ int DLevelScript::RunScript ()
if(pcd == PCD_CALLSTACK)
{
funcnum = STACK(1);
module = FBehavior::StaticGetModule(funcnum>>16);
module = FBehavior::StaticGetModule(funcnum>>LIBRARYID_SHIFT);
--sp;
funcnum &= 0xFFFF; // Clear out tag
@ -8321,7 +8409,7 @@ scriptwait:
{
int playernum = STACK(1);
if (playernum < 0 || playernum >= MAXPLAYERS || !playeringame[playernum] || players[playernum].camera == NULL)
if (playernum < 0 || playernum >= MAXPLAYERS || !playeringame[playernum] || players[playernum].camera == NULL || players[playernum].camera->player != NULL)
{
STACK(1) = -1;
}
@ -8449,7 +8537,8 @@ scriptwait:
case PCD_SAVESTRING:
// Saves the string
{
PushToStack(GlobalACSStrings.AddString(work, Stack, sp));
const int str = GlobalACSStrings.AddString(work, Stack, sp);
PushToStack(str);
STRINGBUILDER_FINISH(work);
}
break;

View File

@ -100,6 +100,7 @@ public:
private:
int FindString(const char *str, size_t len, unsigned int h, unsigned int bucketnum);
int InsertString(FString &str, unsigned int h, unsigned int bucketnum, const SDWORD *stack, int stackdepth);
void FindFirstFreeEntry(unsigned int base);
enum { NUM_BUCKETS = 251 };
enum { FREE_ENTRY = 0xFFFFFFFE }; // Stored in PoolEntry's Next field

View File

@ -698,6 +698,7 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites,
mapthings[count].SkillFilter = 0xffff;
mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH;
mapthings[count].special = 0;
mapthings[count].gravity = FRACUNIT;
if (xsprites != NULL && sprites[i].lotag == 710)
{ // Blood ambient sound

View File

@ -752,7 +752,10 @@ public:
{
ReplyText = GStrings(ReplyText + 1);
}
FBrokenLines *ReplyLines = V_BreakLines (SmallFont, 320-50-10, ReplyText);
FString ReplyString = ReplyText;
if (reply->NeedsGold) ReplyString.AppendFormat(" for %u", reply->ItemCheck[0].Amount);
FBrokenLines *ReplyLines = V_BreakLines (SmallFont, 320-50-10, ReplyString);
mResponses.Push(mResponseLines.Size());
for (j = 0; ReplyLines[j].Width >= 0; ++j)
@ -958,6 +961,7 @@ public:
if (CurNode->SpeakerName != NULL)
{
speakerName = CurNode->SpeakerName;
if (speakerName[0] == '$') speakerName = GStrings(speakerName+1);
}
else
{
@ -1151,7 +1155,7 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang
break;
}
}
if (jump)
if (jump && CurNode->ItemCheckNode > 0)
{
int root = pc->player->ConversationNPC->ConversationRoot;
CurNode = StrifeDialogues[root + CurNode->ItemCheckNode - 1];

View File

@ -915,7 +915,7 @@ void P_NewChaseDir(AActor * actor)
// MBF's monster_backing option. Made an actor flag instead. Also cleaned the code up to make it readable.
// Todo: implement the movement logic
AActor *target = actor->target;
if (target->health > 0 && !actor->IsFriend(target))
if (target->health > 0 && !actor->IsFriend(target) && target != actor->goal)
{ // Live enemy target
if (actor->flags3 & MF3_AVOIDMELEE)

View File

@ -252,7 +252,7 @@ static bool LoadGLVertexes(FileReader * lump)
// GLNodes V1 and V4 are unsupported.
// V1 because the precision is insufficient and
// V4 due to the missing partner segs
Printf("GL nodes v%d found. This format is not supported by "GAMENAME"\n",
Printf("GL nodes v%d found. This format is not supported by " GAMENAME "\n",
(*(int *)gldata == gNd4)? 4:1);
delete [] gldata;

View File

@ -657,10 +657,38 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
FState *diestate = NULL;
int gibhealth = GibHealth();
int iflags4 = inflictor == NULL ? 0 : inflictor->flags4;
bool extremelydead = ((health < gibhealth || iflags4 & MF4_EXTREMEDEATH) && !(iflags4 & MF4_NOEXTREMEDEATH));
// Special check for 'extreme' damage type to ensure that it gets recorded properly as an extreme death for subsequent checks.
if (DamageType == NAME_Extreme)
{
extremelydead = true;
DamageType = NAME_None;
}
// find the appropriate death state. The order is:
//
// 1. If damagetype is not 'none' and death is extreme, try a damage type specific extreme death state
// 2. If no such state is found or death is not extreme try a damage type specific normal death state
// 3. If damagetype is 'ice' and actor is a monster or player, try the generic freeze death (unless prohibited)
// 4. If no state has been found and death is extreme, try the extreme death state
// 5. If no such state is found or death is not extreme try the regular death state.
// 6. If still no state has been found, destroy the actor immediately.
if (DamageType != NAME_None)
{
diestate = FindState (NAME_Death, DamageType, true);
if (extremelydead)
{
FName labels[] = { NAME_Death, NAME_Extreme, DamageType };
diestate = FindState(3, labels, true);
}
if (diestate == NULL)
{
diestate = FindState (NAME_Death, DamageType, true);
if (diestate != NULL) extremelydead = false;
}
if (diestate == NULL)
{
if (DamageType == NAME_Ice)
@ -669,15 +697,13 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
if (!deh.NoAutofreeze && !(flags4 & MF4_NOICEDEATH) && (player || (flags3 & MF3_ISMONSTER)))
{
diestate = FindState(NAME_GenericFreezeDeath);
extremelydead = false;
}
}
}
}
if (diestate == NULL)
{
int flags4 = inflictor == NULL ? 0 : inflictor->flags4;
int gibhealth = GibHealth();
// Don't pass on a damage type this actor cannot handle.
// (most importantly, prevent barrels from passing on ice damage.)
@ -687,33 +713,43 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
DamageType = NAME_None;
}
if ((health < gibhealth || flags4 & MF4_EXTREMEDEATH) && !(flags4 & MF4_NOEXTREMEDEATH))
if (extremelydead)
{ // Extreme death
diestate = FindState (NAME_Death, NAME_Extreme, true);
// If a non-player, mark as extremely dead for the crash state.
if (diestate != NULL && player == NULL && health >= gibhealth)
{
health = gibhealth - 1;
}
// For players, mark the appropriate flag.
else if (player != NULL)
{
player->cheats |= CF_EXTREMELYDEAD;
}
}
if (diestate == NULL)
{ // Normal death
extremelydead = false;
diestate = FindState (NAME_Death);
}
}
if (extremelydead)
{
// We'll only get here if an actual extreme death state was used.
// For players, mark the appropriate flag.
if (player != NULL)
{
player->cheats |= CF_EXTREMELYDEAD;
}
// If a non-player, mark as extremely dead for the crash state.
else if (health >= gibhealth)
{
health = gibhealth - 1;
}
}
if (diestate != NULL)
{
SetState (diestate);
tics -= pr_killmobj() & 3;
if (tics < 1)
tics = 1;
if (tics > 1)
{
tics -= pr_killmobj() & 3;
if (tics < 1)
tics = 1;
}
}
else
{
@ -932,7 +968,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
{ // actor is invulnerable
if (target->player == NULL)
{
if (inflictor == NULL || !(inflictor->flags3 & MF3_FOILINVUL))
if (inflictor == NULL || (!(inflictor->flags3 & MF3_FOILINVUL) && !(flags & DMG_FOILINVUL)))
{
return -1;
}
@ -1107,7 +1143,9 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
&& (pr_damagemobj()&1)
// [RH] But only if not too fast and not flying
&& thrust < 10*FRACUNIT
&& !(target->flags & MF_NOGRAVITY))
&& !(target->flags & MF_NOGRAVITY)
&& (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL))
)
{
ang += ANG180;
thrust *= 4;

View File

@ -1562,9 +1562,21 @@ FUNC(LS_Thing_SetGoal)
ok = true;
if (self->flags & MF_SHOOTABLE)
{
if (self->target == self->goal)
{ // Targeting a goal already? -> don't target it anymore.
// A_Look will set it to the goal, presuming no real targets
// come into view by then.
self->target = NULL;
}
self->goal = goal;
if (arg3 == 0) self->flags5 &=~ MF5_CHASEGOAL;
else self->flags5 |= MF5_CHASEGOAL;
if (arg3 == 0)
{
self->flags5 &= ~MF5_CHASEGOAL;
}
else
{
self->flags5 |= MF5_CHASEGOAL;
}
if (self->target == NULL)
{
self->reactiontime = arg2 * TICRATE;
@ -2545,6 +2557,7 @@ FUNC(LS_Line_SetBlocking)
ML_RAILING,
ML_BLOCKUSE,
ML_BLOCKSIGHT,
ML_BLOCKHITSCAN,
-1
};
@ -2813,6 +2826,11 @@ FUNC(LS_SetPlayerProperty)
{
int i;
if ((ib_compatflags & BCOMPATF_LINKFROZENPROPS) && (mask & (CF_FROZEN | CF_TOTALLYFROZEN)))
{ // Clearing one of these properties clears both of them (if the compat flag is set.)
mask = CF_FROZEN | CF_TOTALLYFROZEN;
}
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])

View File

@ -554,6 +554,7 @@ enum EDmgFlags
DMG_FORCED = 8,
DMG_NO_FACTOR = 16,
DMG_PLAYERATTACK = 32,
DMG_FOILINVUL = 64,
};

View File

@ -53,11 +53,6 @@
#include "r_data/r_translate.h"
#include "g_level.h"
#define WATER_SINK_FACTOR 3
#define WATER_SINK_SMALL_FACTOR 4
#define WATER_SINK_SPEED (FRACUNIT/2)
#define WATER_JUMP_SPEED (FRACUNIT*7/2)
CVAR (Bool, cl_bloodsplats, true, CVAR_ARCHIVE)
CVAR (Int, sv_smartaim, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
CVAR (Bool, cl_doautoaim, false, CVAR_ARCHIVE)
@ -3563,7 +3558,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
else tflags = TRACE_NoSky|TRACE_Impact;
if (!Trace (t1->x, t1->y, shootz, t1->Sector, vx, vy, vz, distance,
MF_SHOOTABLE, ML_BLOCKEVERYTHING, t1, trace,
MF_SHOOTABLE, ML_BLOCKEVERYTHING|ML_BLOCKHITSCAN, t1, trace,
tflags, hitGhosts ? CheckForGhost : CheckForSpectral))
{ // hit nothing
if (puffDefaults == NULL)
@ -4359,14 +4354,17 @@ bool P_NoWayTraverse (AActor *usething, fixed_t endx, fixed_t endy)
void P_UseLines (player_t *player)
{
angle_t angle;
fixed_t x1, y1;
fixed_t x1, y1, usedist;
bool foundline;
foundline = false;
angle = player->mo->angle >> ANGLETOFINESHIFT;
x1 = player->mo->x + (USERANGE>>FRACBITS)*finecosine[angle];
y1 = player->mo->y + (USERANGE>>FRACBITS)*finesine[angle];
usedist = player->mo->UseRange;
// [NS] Now queries the Player's UseRange.
x1 = player->mo->x + FixedMul(usedist, finecosine[angle]);
y1 = player->mo->y + FixedMul(usedist, finesine[angle]);
// old code:
//
@ -4398,13 +4396,20 @@ void P_UseLines (player_t *player)
bool P_UsePuzzleItem (AActor *PuzzleItemUser, int PuzzleItemType)
{
int angle;
fixed_t x1, y1, x2, y2;
fixed_t x1, y1, x2, y2, usedist;
angle = PuzzleItemUser->angle>>ANGLETOFINESHIFT;
x1 = PuzzleItemUser->x;
y1 = PuzzleItemUser->y;
x2 = x1+(USERANGE>>FRACBITS)*finecosine[angle];
y2 = y1+(USERANGE>>FRACBITS)*finesine[angle];
// [NS] If it's a Player, get their UseRange.
if (PuzzleItemUser->player)
usedist = PuzzleItemUser->player->mo->UseRange;
else
usedist = USERANGE;
x2 = x1 + FixedMul(usedist, finecosine[angle]);
y2 = y1 + FixedMul(usedist, finesine[angle]);
FPathTraverse it(x1, y1, x2, y2, PT_ADDLINES|PT_ADDTHINGS);
intercept_t *in;

View File

@ -3993,8 +3993,12 @@ void AActor::HandleSpawnFlags ()
}
if (SpawnFlags & MTF_SECRET)
{
//Printf("Secret %s in sector %i!\n", GetTag(), Sector->sectornum);
flags5 |= MF5_COUNTSECRET;
if (!(flags5 & MF5_COUNTSECRET))
{
//Printf("Secret %s in sector %i!\n", GetTag(), Sector->sectornum);
flags5 |= MF5_COUNTSECRET;
level.total_secrets++;
}
}
}
@ -4712,6 +4716,10 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
mobj->SpawnPoint[2] = mthing->z;
mobj->SpawnAngle = mthing->angle;
mobj->SpawnFlags = mthing->flags;
if (mthing->gravity < 0) mobj->gravity = -mthing->gravity;
else if (mthing->gravity > 0) mobj->gravity = FixedMul(mobj->gravity, mthing->gravity);
else mobj->flags &= ~MF_NOGRAVITY;
P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT);
if (!(mobj->flags2 & MF2_ARGSDEFINED))
@ -5922,7 +5930,15 @@ void AActor::Crash()
if (DamageType != NAME_None)
{
crashstate = FindState(NAME_Crash, DamageType, true);
if (health < GibHealth())
{ // Extreme death
FName labels[] = { NAME_Crash, NAME_Extreme, DamageType };
crashstate = FindState (3, labels, true);
}
if (crashstate == NULL)
{ // Normal death
crashstate = FindState(NAME_Crash, DamageType, true);
}
}
if (crashstate == NULL)
{

View File

@ -256,11 +256,19 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
{
// The userinfo needs to be saved for real players, but it
// needs to come from the save for bots.
userinfo_t uibackup = dst->userinfo;
userinfo_t uibackup;
userinfo_t uibackup2;
uibackup.TransferFrom(dst->userinfo);
uibackup2.TransferFrom(src->userinfo);
int chasecam = dst->cheats & CF_CHASECAM; // Remember the chasecam setting
bool attackdown = dst->attackdown;
bool usedown = dst->usedown;
*dst = *src;
*dst = *src; // To avoid memory leaks at this point the userinfo in src must be empty which is taken care of by the TransferFrom call above.
dst->cheats |= chasecam;
if (dst->isbot)
@ -276,10 +284,11 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
}
bglobal.botnum++;
bglobal.botingame[dst - players] = true;
dst->userinfo.TransferFrom(uibackup2);
}
else
{
dst->userinfo = uibackup;
dst->userinfo.TransferFrom(uibackup);
}
// Validate the skin
dst->userinfo.SkinNumChanged(R_FindSkin(skins[dst->userinfo.GetSkin()].name, dst->CurrentPlayerClass));

View File

@ -250,7 +250,7 @@ static int GetMapIndex(const char *mapname, int lastindex, const char *lumpname,
//
//===========================================================================
MapData *P_OpenMapData(const char * mapname)
MapData *P_OpenMapData(const char * mapname, bool justcheck)
{
MapData * map = new MapData;
FileReader * wadReader = NULL;
@ -329,7 +329,20 @@ MapData *P_OpenMapData(const char * mapname)
// Since levels must be stored in WADs they can't really have full
// names and for any valid level lump this always returns the short name.
const char * lumpname = Wads.GetLumpFullName(lump_name + i);
index = GetMapIndex(mapname, index, lumpname, i != 1 || Wads.LumpLength(lump_name + i) == 0);
try
{
index = GetMapIndex(mapname, index, lumpname, !justcheck);
}
catch(...)
{
delete map;
throw;
}
if (index == -2)
{
delete map;
return NULL;
}
if (index == ML_BEHAVIOR) map->HasBehavior = true;
// The next lump is not part of this map anymore
@ -461,7 +474,20 @@ MapData *P_OpenMapData(const char * mapname)
if (i>0)
{
index = GetMapIndex(maplabel, index, lumpname, true);
try
{
index = GetMapIndex(maplabel, index, lumpname, !justcheck);
}
catch(...)
{
delete map;
throw;
}
if (index == -2)
{
delete map;
return NULL;
}
if (index == ML_BEHAVIOR) map->HasBehavior = true;
// The next lump is not part of this map anymore
@ -492,7 +518,7 @@ MapData *P_OpenMapData(const char * mapname)
bool P_CheckMapData(const char *mapname)
{
MapData *mapd = P_OpenMapData(mapname);
MapData *mapd = P_OpenMapData(mapname, true);
if (mapd == NULL) return false;
delete mapd;
return true;
@ -1734,6 +1760,7 @@ void P_LoadThings (MapData * map)
memset (&mti[i], 0, sizeof(mti[i]));
mti[i].gravity = FRACUNIT;
mti[i].Conversation = 0;
mti[i].SkillFilter = MakeSkill(flags);
mti[i].ClassFilter = 0xffff; // Doom map format doesn't have class flags so spawn for all player classes
@ -1809,6 +1836,7 @@ void P_LoadThings2 (MapData * map)
mti[i].ClassFilter = (mti[i].flags & MTF_CLASS_MASK) >> MTF_CLASS_SHIFT;
mti[i].flags &= ~(MTF_SKILLMASK|MTF_CLASS_MASK);
mti[i].Conversation = 0;
mti[i].gravity = FRACUNIT;
}
delete[] mtp;
}
@ -3592,7 +3620,7 @@ void P_SetupLevel (char *lumpname, int position)
P_FreeLevelData ();
interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level.
MapData *map = P_OpenMapData(lumpname);
MapData *map = P_OpenMapData(lumpname, true);
if (map == NULL)
{
I_Error("Unable to open map '%s'\n", lumpname);

View File

@ -94,7 +94,7 @@ struct MapData
void GetChecksum(BYTE cksum[16]);
};
MapData * P_OpenMapData(const char * mapname);
MapData * P_OpenMapData(const char * mapname, bool justcheck);
bool P_CheckMapData(const char * mapname);

View File

@ -639,12 +639,21 @@ void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass,
{
next = actor->snext;
// Only affect actors touching the 3D floor
if (actor->z + actor->height > sec->floorplane.ZatPoint(actor->x, actor->y))
fixed_t z1 = sec->floorplane.ZatPoint(actor->x, actor->y);
fixed_t z2 = sec->ceilingplane.ZatPoint(actor->x, actor->y);
if (z2 < z1)
{
// Account for Vavoom-style 3D floors
fixed_t zz = z1;
z1 = z2;
z2 = zz;
}
if (actor->z + actor->height > z1)
{
// If DAMAGE_IN_AIR is used, anything not beneath the 3D floor will be
// damaged (so, anything touching it or above it). Other 3D floors between
// the actor and this one will not stop this effect.
if ((flags & DAMAGE_IN_AIR) || actor->z <= sec->ceilingplane.ZatPoint(actor->x, actor->y))
if ((flags & DAMAGE_IN_AIR) || actor->z <= z2)
{
// Here we pass the DAMAGE_IN_AIR flag to disable the floor check, since it
// only works with the real sector's floor. We did the appropriate height checks

View File

@ -763,7 +763,7 @@ protected:
fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
int usespecials);
friend bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower=false);
fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower);
friend bool EV_FloorCrushStop (int tag);
friend bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed);
private:
@ -774,7 +774,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
int usespecials);
bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower);
fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower=false);
bool EV_FloorCrushStop (int tag);
bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed);

View File

@ -475,6 +475,7 @@ public:
FString arg0str, arg1str;
memset(th, 0, sizeof(*th));
th->gravity = FRACUNIT;
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{
@ -515,6 +516,11 @@ public:
th->special = CheckInt(key);
break;
case NAME_Gravity:
CHECK_N(Zd | Zdt)
th->gravity = CheckFixed(key);
break;
case NAME_Arg0:
case NAME_Arg1:
case NAME_Arg2:
@ -921,6 +927,10 @@ public:
Flag(ld->flags, ML_BLOCKSIGHT, key);
continue;
case NAME_blockhitscan:
Flag(ld->flags, ML_BLOCKHITSCAN, key);
continue;
// [Dusk] lock number
case NAME_Locknumber:
ld->locknumber = CheckInt(key);
@ -1326,7 +1336,11 @@ public:
continue;
case NAME_hidden:
sec->MoreFlags |= SECF_HIDDEN;
Flag(sec->MoreFlags, SECF_HIDDEN, key);
break;
case NAME_Waterzone:
Flag(sec->MoreFlags, SECF_UNDERWATER, key);
break;
default:

View File

@ -224,7 +224,6 @@ class USDFParser : public UDMFParserBase
if (reply->ItemCheck.Size() > 0)
{
if (reply->ItemCheck[0].Amount <= 0) reply->NeedsGold = false;
if (reply->NeedsGold) ReplyString.AppendFormat(" for %u", reply->ItemCheck[0].Amount);
}
reply->Reply = ncopystring(ReplyString);
@ -288,6 +287,7 @@ class USDFParser : public UDMFParserBase
//node->ItemCheckCount[0] = node->ItemCheckCount[1] = node->ItemCheckCount[2] = -1;
node->ThisNodeNum = StrifeDialogues.Push(node);
node->ItemCheckNode = -1;
FString SpeakerName;
FString Dialogue;

View File

@ -309,12 +309,120 @@ player_t::player_t()
ConversationFaceTalker(0)
{
memset (&cmd, 0, sizeof(cmd));
memset (&userinfo, 0, sizeof(userinfo));
memset (frags, 0, sizeof(frags));
memset (psprites, 0, sizeof(psprites));
memset (&skill, 0, sizeof(skill));
}
player_t &player_t::operator=(const player_t &p)
{
mo = p.mo;
playerstate = p.playerstate;
cmd = p.cmd;
original_cmd = p.original_cmd;
original_oldbuttons = p.original_oldbuttons;
// Intentionally not copying userinfo!
cls = p.cls;
DesiredFOV = p.DesiredFOV;
FOV = p.FOV;
viewz = p.viewz;
viewheight = p.viewheight;
deltaviewheight = p.deltaviewheight;
bob = p.bob;
velx = p.velx;
vely = p.vely;
centering = p.centering;
turnticks = p.turnticks;
attackdown = p.attackdown;
usedown = p.usedown;
oldbuttons = p.oldbuttons;
health = p.health;
inventorytics = p.inventorytics;
CurrentPlayerClass = p.CurrentPlayerClass;
backpack = p.backpack;
memcpy(frags, &p.frags, sizeof(frags));
fragcount = p.fragcount;
lastkilltime = p.lastkilltime;
multicount = p.multicount;
spreecount = p.spreecount;
WeaponState = p.WeaponState;
ReadyWeapon = p.ReadyWeapon;
PendingWeapon = p.PendingWeapon;
cheats = p.cheats;
timefreezer = p.timefreezer;
refire = p.refire;
inconsistant = p.inconsistant;
waiting = p.waiting;
killcount = p.killcount;
itemcount = p.itemcount;
secretcount = p.secretcount;
damagecount = p.damagecount;
bonuscount = p.bonuscount;
hazardcount = p.hazardcount;
poisoncount = p.poisoncount;
poisontype = p.poisontype;
poisonpaintype = p.poisonpaintype;
poisoner = p.poisoner;
attacker = p.attacker;
extralight = p.extralight;
fixedcolormap = p.fixedcolormap;
fixedlightlevel = p.fixedlightlevel;
memcpy(psprites, &p.psprites, sizeof(psprites));
morphTics = p.morphTics;
MorphedPlayerClass = p.MorphedPlayerClass;
MorphStyle = p.MorphStyle;
MorphExitFlash = p.MorphExitFlash;
PremorphWeapon = p.PremorphWeapon;
chickenPeck = p.chickenPeck;
jumpTics = p.jumpTics;
respawn_time = p.respawn_time;
camera = p.camera;
air_finished = p.air_finished;
LastDamageType = p.LastDamageType;
savedyaw = p.savedyaw;
savedpitch = p.savedpitch;
angle = p.angle;
dest = p.dest;
prev = p.prev;
enemy = p.enemy;
missile = p.missile;
mate = p.mate;
last_mate = p.last_mate;
settings_controller = p.settings_controller;
skill = p.skill;
t_active = p.t_active;
t_respawn = p.t_respawn;
t_strafe = p.t_strafe;
t_react = p.t_react;
t_fight = p.t_fight;
t_roam = p.t_roam;
t_rocket = p.t_rocket;
isbot = p.isbot;
first_shot = p.first_shot;
sleft = p.sleft;
allround = p.allround;
oldx = p.oldx;
oldy = p.oldy;
BlendR = p.BlendR;
BlendG = p.BlendG;
BlendB = p.BlendB;
BlendA = p.BlendA;
LogText = p.LogText;
MinPitch = p.MinPitch;
MaxPitch = p.MaxPitch;
crouching = p.crouching;
crouchdir = p.crouchdir;
crouchfactor = p.crouchfactor;
crouchoffset = p.crouchoffset;
crouchviewdelta = p.crouchviewdelta;
weapons = p.weapons;
ConversationNPC = p.ConversationNPC;
ConversationPC = p.ConversationPC;
ConversationNPCAngle = p.ConversationNPCAngle;
ConversationFaceTalker = p.ConversationFaceTalker;
return *this;
}
// This function supplements the pointer cleanup in dobject.cpp, because
// player_t is not derived from DObject. (I tried it, and DestroyScan was
// unable to properly determine the player object's type--possibly
@ -474,6 +582,14 @@ void APlayerPawn::Serialize (FArchive &arc)
{
arc << GruntSpeed << FallingScreamMinSpeed << FallingScreamMaxSpeed;
}
if (SaveVersion >= 4502)
{
arc << UseRange;
}
if (SaveVersion >= 4503)
{
arc << AirCapacity;
}
}
//===========================================================================
@ -1063,7 +1179,7 @@ bool APlayerPawn::ResetAirSupply (bool playgasp)
{
S_Sound (this, CHAN_VOICE, "*gasp", 1, ATTN_NORM);
}
if (level.airsupply> 0) player->air_finished = level.time + level.airsupply;
if (level.airsupply> 0 && player->mo->AirCapacity > 0) player->air_finished = level.time + FixedMul(level.airsupply, player->mo->AirCapacity);
else player->air_finished = INT_MAX;
return wasdrowning;
}

View File

@ -174,7 +174,15 @@ void R_InitPlanes ()
void R_DeinitPlanes ()
{
fakeActive = 0;
R_ClearPlanes(false);
// do not use R_ClearPlanes because at this point the screen pointer is no longer valid.
for (int i = 0; i <= MAXVISPLANES; i++) // new code -- killough
{
for (*freehead = visplanes[i], visplanes[i] = NULL; *freehead; )
{
freehead = &(*freehead)->next;
}
}
for (visplane_t *pl = freetail; pl != NULL; )
{
visplane_t *next = pl->next;
@ -490,7 +498,7 @@ void R_MapColoredPlane (int y, int x1)
void R_ClearPlanes (bool fullclear)
{
int i, max;
int i;
// Don't clear fake planes if not doing a full clear.
if (!fullclear)
@ -516,7 +524,6 @@ void R_ClearPlanes (bool fullclear)
}
else
{
max = fullclear ? MAXVISPLANES : MAXVISPLANES-1;
for (i = 0; i <= MAXVISPLANES; i++) // new code -- killough
{
for (*freehead = visplanes[i], visplanes[i] = NULL; *freehead; )
@ -524,10 +531,7 @@ void R_ClearPlanes (bool fullclear)
freehead = &(*freehead)->next;
}
}
}
if (fullclear)
{
// opening / clipping determination
clearbufshort (floorclip, viewwidth, viewheight);
// [RH] clip ceiling to console bottom

View File

@ -828,7 +828,7 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2)
{
if (sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0())
{
lightlist_t *lit = &backsector->e->XFloor.lightlist[i];
lightlist_t *lit = &backsector->e->XFloor.lightlist[j];
basecolormap = lit->extra_colormap;
wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource == NULL) + r_actualextralight);
break;

View File

@ -62,6 +62,9 @@
extern bool DrawFSHUD; // [RH] Defined in d_main.cpp
EXTERN_CVAR (Bool, cl_capfps)
extern lighttable_t* fixedcolormap;
extern FSpecialColormap*realfixedcolormap;
// TYPES -------------------------------------------------------------------
struct InterpolationViewer
@ -1005,6 +1008,11 @@ void FCanvasTextureInfo::UpdateAll ()
{
FCanvasTextureInfo *probe;
// curse Doom's overuse of global variables in the renderer.
// These get clobbered by rendering to a camera texture but they need to be preserved so the final rendering can be done with the correct palette.
unsigned char *savecolormap = fixedcolormap;
FSpecialColormap *savecm = realfixedcolormap;
for (probe = List; probe != NULL; probe = probe->Next)
{
if (probe->Viewpoint != NULL && probe->Texture->bNeedsUpdate)
@ -1012,6 +1020,9 @@ void FCanvasTextureInfo::UpdateAll ()
Renderer->RenderTextureView(probe->Texture, probe->Viewpoint, probe->FOV);
}
}
fixedcolormap = savecolormap;
realfixedcolormap = savecm;
}
//==========================================================================

View File

@ -243,7 +243,7 @@ bool F7ZFile::Open(bool quiet)
Archive = NULL;
if (!quiet)
{
Printf("\n"TEXTCOLOR_RED"%s: ", Filename);
Printf("\n" TEXTCOLOR_RED "%s: ", Filename);
if (res == SZ_ERROR_UNSUPPORTED)
{
Printf("Decoder does not support this archive\n");

View File

@ -63,7 +63,7 @@ bool FPlayList::ChangeList (const char *path)
if ( (file = fopen (path, "rb")) == NULL)
{
Printf ("Could not open "TEXTCOLOR_BOLD"%s"TEXTCOLOR_NORMAL": %s\n", path, strerror(errno));
Printf ("Could not open " TEXTCOLOR_BOLD "%s" TEXTCOLOR_NORMAL ": %s\n", path, strerror(errno));
return false;
}

View File

@ -1683,7 +1683,7 @@ bool S_GetSoundPlayingInfo (const FPolyObj *poly, int sound_id)
//
//==========================================================================
bool S_IsChannelUsed(AActor *actor, int channel, int *seen)
static bool S_IsChannelUsed(AActor *actor, int channel, int *seen)
{
if (*seen & (1 << channel))
{

View File

@ -922,7 +922,7 @@ void STACK_ARGS FScanner::ScriptMessage (const char *message, ...)
va_end (arglist);
}
Printf (TEXTCOLOR_RED"Script error, \"%s\" line %d:\n"TEXTCOLOR_RED"%s\n", ScriptName.GetChars(),
Printf (TEXTCOLOR_RED "Script error, \"%s\" line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(),
AlreadyGot? AlreadyGotLine : Line, composed.GetChars());
}

View File

@ -616,7 +616,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
const char *str;
if((str=getenv("KDE_FULL_SESSION")) && strcmp(str, "true") == 0)
{
FString cmd("kdialog --title \""GAMESIG" ");
FString cmd("kdialog --title \"" GAMESIG " ");
cmd << GetVersionString() << ": Select an IWAD to use\""
" --menu \"ZDoom found more than one IWAD\n"
"Select from the list below to determine which one to use:\"";
@ -749,6 +749,8 @@ int I_FindClose (void *handle)
findstate_t *state = (findstate_t *)handle;
if (handle != (void*)-1 && state->count > 0)
{
for(int i = 0;i < state->count;++i)
free (state->namelist[i]);
state->count = 0;
free (state->namelist);
state->namelist = NULL;

View File

@ -156,7 +156,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
cancelled = false;
app = [NSApplication sharedApplication];
id windowTitle = [NSString stringWithUTF8String:GAMESIG " " DOTVERSIONSTR ": Select an IWAD to use"];
id windowTitle = [NSString stringWithFormat:@GAMESIG " %s: Select an IWAD to use", GetVersionString()];
NSRect frame = NSMakeRect(0, 0, 440, 450);
window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO];

View File

@ -108,7 +108,6 @@ CUSTOM_CVAR (Float, snd_waterlp, 250, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
}
#ifndef NO_FMOD
#if FMOD_VERSION < 0x43400
#define FMOD_OPENSTATE_PLAYING FMOD_OPENSTATE_STREAMING
#endif
@ -734,8 +733,8 @@ bool FMODSoundRenderer::Init()
}
if (wrongver != NULL)
{
Printf (" "TEXTCOLOR_ORANGE"Error! You are using %s version of FMOD (%x.%02x.%02x).\n"
" "TEXTCOLOR_ORANGE"This program was built for version %x.%02x.%02x\n",
Printf (" " TEXTCOLOR_ORANGE "Error! You are using %s version of FMOD (%x.%02x.%02x).\n"
" " TEXTCOLOR_ORANGE "This program was built for version %x.%02x.%02x\n",
wrongver,
version >> 16, (version >> 8) & 255, version & 255,
FMOD_VERSION >> 16, (FMOD_VERSION >> 8) & 255, FMOD_VERSION & 255);
@ -1263,15 +1262,15 @@ void FMODSoundRenderer::PrintStatus()
unsigned int bufferlength;
int numbuffers;
Printf ("Loaded FMOD version: "TEXTCOLOR_GREEN"%x.%02x.%02x\n", ActiveFMODVersion >> 16,
Printf ("Loaded FMOD version: " TEXTCOLOR_GREEN "%x.%02x.%02x\n", ActiveFMODVersion >> 16,
(ActiveFMODVersion >> 8) & 255, ActiveFMODVersion & 255);
if (FMOD_OK == Sys->getOutput(&output))
{
Printf ("Output type: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(OutputNames, output));
Printf ("Output type: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(OutputNames, output));
}
if (FMOD_OK == Sys->getSpeakerMode(&speakermode))
{
Printf ("Speaker mode: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(SpeakerModeNames, speakermode));
Printf ("Speaker mode: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(SpeakerModeNames, speakermode));
}
if (FMOD_OK == Sys->getDriver(&driver))
{
@ -1280,19 +1279,19 @@ void FMODSoundRenderer::PrintStatus()
{
strcpy(name, "Unknown");
}
Printf ("Driver: "TEXTCOLOR_GREEN"%d"TEXTCOLOR_NORMAL" ("TEXTCOLOR_ORANGE"%s"TEXTCOLOR_NORMAL")\n", driver, name);
Printf ("Driver: " TEXTCOLOR_GREEN "%d" TEXTCOLOR_NORMAL " (" TEXTCOLOR_ORANGE "%s" TEXTCOLOR_NORMAL ")\n", driver, name);
DumpDriverCaps(Driver_Caps, Driver_MinFrequency, Driver_MaxFrequency);
}
if (FMOD_OK == Sys->getSoftwareFormat(&samplerate, &format, &numoutputchannels, NULL, &resampler, NULL))
{
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: "TEXTCOLOR_GREEN"%d\n", samplerate);
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer format: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(SoundFormatNames, format));
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer channels: "TEXTCOLOR_GREEN"%d\n", numoutputchannels);
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer resampler: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(ResamplerNames, resampler));
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: " TEXTCOLOR_GREEN "%d\n", samplerate);
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer format: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(SoundFormatNames, format));
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer channels: " TEXTCOLOR_GREEN "%d\n", numoutputchannels);
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer resampler: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(ResamplerNames, resampler));
}
if (FMOD_OK == Sys->getDSPBufferSize(&bufferlength, &numbuffers))
{
Printf (TEXTCOLOR_LIGHTBLUE "DSP buffers: "TEXTCOLOR_GREEN"%u samples x %d\n", bufferlength, numbuffers);
Printf (TEXTCOLOR_LIGHTBLUE "DSP buffers: " TEXTCOLOR_GREEN "%u samples x %d\n", bufferlength, numbuffers);
}
}
@ -1304,8 +1303,8 @@ void FMODSoundRenderer::PrintStatus()
void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int maxfrequency)
{
Printf (TEXTCOLOR_OLIVE " Min. frequency: "TEXTCOLOR_GREEN"%d\n", minfrequency);
Printf (TEXTCOLOR_OLIVE " Max. frequency: "TEXTCOLOR_GREEN"%d\n", maxfrequency);
Printf (TEXTCOLOR_OLIVE " Min. frequency: " TEXTCOLOR_GREEN "%d\n", minfrequency);
Printf (TEXTCOLOR_OLIVE " Max. frequency: " TEXTCOLOR_GREEN "%d\n", maxfrequency);
Printf (" Features:\n");
if (caps == 0) Printf(TEXTCOLOR_OLIVE " None\n");
if (caps & FMOD_CAPS_HARDWARE) Printf(TEXTCOLOR_OLIVE " Hardware mixing\n");
@ -1320,7 +1319,7 @@ void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int max
{
Printf("\n");
}
if (caps & FMOD_CAPS_REVERB_LIMITED) Printf("TEXTCOLOR_OLIVE Limited reverb\n");
if (caps & FMOD_CAPS_REVERB_LIMITED) Printf(TEXTCOLOR_OLIVE " Limited reverb\n");
}
//==========================================================================
@ -1388,11 +1387,11 @@ FString FMODSoundRenderer::GatherStats()
}
#endif
out.Format ("%d channels,"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%% CPU "
"(DSP:"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%% "
"Stream:"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%% "
"Geometry:"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%% "
"Update:"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%%)",
out.Format ("%d channels," TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% CPU "
"(DSP:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% "
"Stream:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% "
"Geometry:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% "
"Update:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%%)",
channels, total, dsp, stream, geometry, update);
return out;
}

View File

@ -620,10 +620,10 @@ FString FluidSynthMIDIDevice::GetStats()
fluid_settings_getint(FluidSettings, "synth.polyphony", &maxpoly);
CritSec.Leave();
out.Format("Voices: "TEXTCOLOR_YELLOW"%3d"TEXTCOLOR_NORMAL"/"TEXTCOLOR_ORANGE"%3d"TEXTCOLOR_NORMAL"("TEXTCOLOR_RED"%3d"TEXTCOLOR_NORMAL")"
TEXTCOLOR_YELLOW"%6.2f"TEXTCOLOR_NORMAL"%% CPU "
"Reverb: "TEXTCOLOR_YELLOW"%3s"TEXTCOLOR_NORMAL
" Chorus: "TEXTCOLOR_YELLOW"%3s",
out.Format("Voices: " TEXTCOLOR_YELLOW "%3d" TEXTCOLOR_NORMAL "/" TEXTCOLOR_ORANGE "%3d" TEXTCOLOR_NORMAL "(" TEXTCOLOR_RED "%3d" TEXTCOLOR_NORMAL ")"
TEXTCOLOR_YELLOW "%6.2f" TEXTCOLOR_NORMAL "%% CPU "
"Reverb: " TEXTCOLOR_YELLOW "%3s" TEXTCOLOR_NORMAL
" Chorus: " TEXTCOLOR_YELLOW "%3s",
voices, polyphony, maxpoly, load, reverb, chorus);
return out;
}

View File

@ -1376,7 +1376,7 @@ void OpenALSoundRenderer::SetSfxPaused(bool paused, int slot)
}
}
void OpenALSoundRenderer::SetInactive(EInactiveState)
void OpenALSoundRenderer::SetInactive(SoundRenderer::EInactiveState)
{
}

View File

@ -74,7 +74,7 @@ public:
virtual void SetSfxVolume(float volume);
virtual void SetMusicVolume(float volume);
virtual SoundHandle LoadSound(BYTE *sfxdata, int length);
virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend);
virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1);
virtual void UnloadSound(SoundHandle sfx);
virtual unsigned int GetMSLength(SoundHandle sfx);
virtual unsigned int GetSampleLength(SoundHandle sfx);
@ -104,7 +104,7 @@ public:
virtual void SetSfxPaused(bool paused, int slot);
// Pauses or resumes *every* channel, including environmental reverb.
virtual void SetInactive(EInactiveState state);
virtual void SetInactive(SoundRenderer::EInactiveState inactive);
// Updates the volume, separation, and pitch of a sound channel.
virtual void UpdateSoundParams3D(SoundListener *listener, FISoundChannel *chan, bool areasound, const FVector3 &pos, const FVector3 &vel);

View File

@ -463,7 +463,7 @@ void STAT_ChangeLevel(const char *newl)
{
// we reached the end of this episode
int wad = 0;
MapData * map = P_OpenMapData(StartEpisode->mEpisodeMap);
MapData * map = P_OpenMapData(StartEpisode->mEpisodeMap, false);
if (map != NULL)
{
wad = Wads.GetLumpFile(map->lumpnum);

View File

@ -659,6 +659,17 @@ void FTextureManager::ParseCameraTexture(FScanner &sc)
sc.UnGet ();
}
}
if (sc.GetString())
{
if (sc.Compare("WorldPanning"))
{
viewer->bWorldPanning = true;
}
else
{
sc.UnGet();
}
}
viewer->SetScaledSize(fitwidth, fitheight);
}

View File

@ -233,13 +233,13 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl
NumParts = SAFESHORT(mtexture.d->patchcount);
}
if (NumParts <= 0)
if (NumParts < 0)
{
I_FatalError ("Bad texture directory");
}
UseType = FTexture::TEX_Wall;
Parts = new TexPart[NumParts];
Parts = NumParts > 0 ? new TexPart[NumParts] : NULL;
Width = SAFESHORT(mtexture.d->width);
Height = SAFESHORT(mtexture.d->height);
strncpy (Name, (const char *)mtexture.d->name, 8);
@ -906,7 +906,7 @@ void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int d
// There is bizzarely a Doom editing tool that writes to the
// first two elements of columndirectory, so I can't check those.
if (SAFESHORT(tex->patchcount) <= 0 ||
if (SAFESHORT(tex->patchcount) < 0 ||
tex->columndirectory[2] != 0 ||
tex->columndirectory[3] != 0)
{

View File

@ -127,7 +127,7 @@ void FTextureManager::DeleteAll()
{
if (mAnimatedDoors[i].TextureFrames != NULL)
{
delete mAnimatedDoors[i].TextureFrames;
delete[] mAnimatedDoors[i].TextureFrames;
mAnimatedDoors[i].TextureFrames = NULL;
}
}

View File

@ -70,6 +70,7 @@
#include "m_bbox.h"
#include "r_data/r_translate.h"
#include "p_trace.h"
#include "gstrings.h"
static FRandom pr_camissile ("CustomActorfire");
@ -1403,7 +1404,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
}
if (!PuffType) PuffType = PClass::FindClass(NAME_BulletPuff);
int puffFlags = LAF_ISMELEEATTACK | (flags & CPF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
int puffFlags = LAF_ISMELEEATTACK | ((flags & CPF_NORANDOMPUFFZ) ? LAF_NORANDOMPUFFZ : 0);
P_LineAttack (self, angle, Range, pitch, Damage, NAME_Melee, PuffType, puffFlags, &linetarget, &actualdamage);
@ -1425,7 +1426,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
if (flags & CPF_PULLIN) self->flags |= MF_JUSTATTACKED;
if (flags & CPF_DAGGER) P_DaggerAlert (self, linetarget);
}
}
@ -1746,6 +1746,7 @@ enum SIX_Flags
SIXF_TRANSFERSCALE = 1 << 14,
SIXF_TRANSFERSPECIAL = 1 << 15,
SIXF_CLEARCALLERSPECIAL = 1 << 16,
SIXF_TRANSFERSTENCILCOL = 1 << 17,
};
static bool InitSpawnedItem(AActor *self, AActor *mo, int flags)
@ -1858,6 +1859,10 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags)
self->special = 0;
memset(self->args, 0, sizeof(self->args));
}
if (flags & SIXF_TRANSFERSTENCILCOL)
{
mo->fillcolor = self->fillcolor;
}
return true;
}
@ -2133,6 +2138,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Print)
ACTION_PARAM_FLOAT(time, 1);
ACTION_PARAM_NAME(fontname, 2);
if (text[0] == '$') text = GStrings(text+1);
if (self->CheckLocalView (consoleplayer) ||
(self->target!=NULL && self->target->CheckLocalView (consoleplayer)))
{
@ -2171,6 +2177,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PrintBold)
float saved = con_midtime;
FFont *font = NULL;
if (text[0] == '$') text = GStrings(text+1);
if (fontname != NAME_None)
{
font = V_GetFont(fontname);
@ -2196,11 +2203,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Log)
{
ACTION_PARAM_START(1);
ACTION_PARAM_STRING(text, 0);
if (text[0] == '$') text = GStrings(text+1);
Printf("%s\n", text);
ACTION_SET_RESULT(false); // Prints should never set the result for inventory state chains!
}
//===========================================================================
//=========================================================================
//
// A_LogInt
//
@ -4925,6 +4934,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTics)
ACTION_PARAM_START(1);
ACTION_PARAM_INT(tics_to_set, 0);
if (stateowner != self && self->player != NULL && stateowner->IsKindOf(RUNTIME_CLASS(AWeapon)))
{ // Is this a weapon? Need to check psp states for a match, then. Blah.
for (int i = 0; i < NUMPSPRITES; ++i)
{
if (self->player->psprites[i].state == CallingState)
{
self->player->psprites[i].tics = tics_to_set;
return;
}
}
}
// Just set tics for self.
self->tics = tics_to_set;
}
@ -4941,3 +4962,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetDamageType)
self->DamageType = damagetype;
}
//==========================================================================
//
// A_DropItem
//
//==========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropItem)
{
ACTION_PARAM_START(3);
ACTION_PARAM_CLASS(spawntype, 0);
ACTION_PARAM_INT(amount, 1);
ACTION_PARAM_INT(chance, 2);
P_DropItem(self, spawntype, amount, chance);
}

View File

@ -184,6 +184,7 @@ static FFlagDef ActorFlags[]=
DEFINE_FLAG(MF5, DONTDRAIN, AActor, flags5),
DEFINE_FLAG(MF5, NODROPOFF, AActor, flags5),
DEFINE_FLAG(MF5, NOFORWARDFALL, AActor, flags5),
DEFINE_FLAG(MF5, COUNTSECRET, AActor, flags5),
DEFINE_FLAG(MF5, NODAMAGE, AActor, flags5),
DEFINE_FLAG(MF5, BLOODSPLATTER, AActor, flags5),
@ -233,6 +234,7 @@ static FFlagDef ActorFlags[]=
DEFINE_FLAG(MF6, DOHARMSPECIES, AActor, flags6),
DEFINE_FLAG(MF6, POISONALWAYS, AActor, flags6),
DEFINE_FLAG(MF6, NOTAUTOAIMED, AActor, flags6),
DEFINE_FLAG(MF6, NOTONAUTOMAP, AActor, flags6),
// Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),

View File

@ -867,7 +867,7 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
OPTIONAL = 1
};
bool error = false;
unsigned int error = 0;
const AFuncDesc *afd;
FName funcname;
FString args;
@ -876,8 +876,8 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0)
{
sc.ScriptMessage ("action functions can only be imported by internal class and actor definitions!");
error++;
sc.ScriptMessage ("Action functions can only be imported by internal class and actor definitions!");
++error;
}
sc.MustGetToken(TK_Native);
@ -887,7 +887,7 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
if (afd == NULL)
{
sc.ScriptMessage ("The function '%s' has not been exported from the executable.", sc.String);
error++;
++error;
}
sc.MustGetToken('(');
if (!sc.CheckToken(')'))
@ -998,7 +998,7 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
}
if (error)
{
FScriptPosition::ErrorCounter++;
FScriptPosition::ErrorCounter += error;
}
else if (cls->Symbols.AddSymbol (sym) == NULL)
{

View File

@ -2113,9 +2113,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, strength, F, Inventory)
I_Error("\"powerup.strength\" requires an actor of type \"Powerup\"\n");
return;
}
// Puts a percent value in the 0.0..1.0 range
PROP_FIXED_PARM(f, 0);
*pStrength = f / 100;
*pStrength = f;
}
//==========================================================================
@ -2410,6 +2409,24 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, viewheight, F, PlayerPawn)
defaults->ViewHeight = z;
}
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY_PREFIX(player, userange, F, PlayerPawn)
{
PROP_FIXED_PARM(z, 0);
defaults->UseRange = z;
}
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY_PREFIX(player, aircapacity, F, PlayerPawn)
{
PROP_FIXED_PARM(z, 0);
defaults->AirCapacity = z;
}
//==========================================================================
//
//==========================================================================

View File

@ -76,7 +76,7 @@ const char *GetVersionString();
// Use 4500 as the base git save version, since it's higher than the
// SVN revision ever got.
#define SAVEVER 4501
#define SAVEVER 4503
#define SAVEVERSTRINGIFY2(x) #x
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)

View File

@ -62,7 +62,7 @@ typedef enum
CVAR (Bool, wi_percents, true, CVAR_ARCHIVE)
CVAR (Bool, wi_showtotaltime, true, CVAR_ARCHIVE)
CVAR (Bool, wi_noautostartmap, false, CVAR_ARCHIVE)
CVAR (Bool, wi_noautostartmap, false, CVAR_USERINFO|CVAR_ARCHIVE)
void WI_loadData ();
@ -1098,11 +1098,28 @@ void WI_updateNoState ()
{
WI_updateAnimatedBack();
if (acceleratestage)
{
cnt = 0;
}
else
{
bool noauto = noautostartmap;
if (!wi_noautostartmap && !noautostartmap) cnt--;
if (acceleratestage) cnt=0;
for (int i = 0; !noauto && i < MAXPLAYERS; ++i)
{
if (playeringame[i])
{
noauto |= players[i].userinfo.GetNoAutostartMap();
}
}
if (!noauto)
{
cnt--;
}
}
if (cnt==0)
if (cnt == 0)
{
WI_End();
G_WorldDone();
@ -1947,7 +1964,7 @@ void WI_Ticker(void)
if (level.info->InterMusic.IsNotEmpty())
S_ChangeMusic(level.info->InterMusic, level.info->intermusicorder);
else
S_ChangeMusic (gameinfo.intermissionMusic.GetChars());
S_ChangeMusic (gameinfo.intermissionMusic.GetChars(), gameinfo.intermissionOrder);
}

View File

@ -1569,3 +1569,31 @@ unsigned int I_MakeRNGSeed()
CryptReleaseContext(prov, 0);
return seed;
}
//==========================================================================
//
// I_GetLongPathName
//
// Returns the long version of the path, or the original if there isn't
// anything worth changing.
//
//==========================================================================
FString I_GetLongPathName(FString shortpath)
{
DWORD buffsize = GetLongPathName(shortpath.GetChars(), NULL, 0);
if (buffsize == 0)
{ // nothing to change (it doesn't exist, maybe?)
return shortpath;
}
TCHAR *buff = new TCHAR[buffsize];
DWORD buffsize2 = GetLongPathName(shortpath.GetChars(), buff, buffsize);
if (buffsize2 >= buffsize)
{ // Failure! Just return the short path
delete[] buff;
return shortpath;
}
FString longpath(buff, buffsize2);
delete[] buff;
return longpath;
}

View File

@ -155,6 +155,9 @@ typedef _W64 long WLONG_PTR;
typedef long WLONG_PTR;
#endif
// Wrapper for GetLongPathName
FString I_GetLongPathName(FString shortpath);
// Directory searching routines
// Mirror WIN32_FIND_DATAA in <winbase.h>

View File

@ -1,11 +1,3 @@
cmake_minimum_required( VERSION 2.4 )
get_target_property(ZIPDIR_EXE zipdir LOCATION)
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/zdoom.pk3
COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/zdoom.pk3 ${CMAKE_CURRENT_SOURCE_DIR}/static
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/zdoom.pk3 $<TARGET_FILE_DIR:zdoom>
DEPENDS zipdir ${CMAKE_CURRENT_SOURCE_DIR}/static )
add_custom_target( pk3 ALL
DEPENDS ${ZDOOM_OUTPUT_DIR}/zdoom.pk3 )
add_pk3(zdoom.pk3 ${CMAKE_CURRENT_SOURCE_DIR}/static)

View File

@ -84,7 +84,7 @@ ACTOR Actor native //: Thinker
action native A_VileChase();
action native A_VileStart();
action native A_VileTarget(class<Actor> fire = "ArchvileFire");
action native A_VileAttack(sound snd = "vile/stop", int initialdmg = 20, int blastdmg = 70, int blastradius = 70, float thrustfac = 1.0, name damagetype = "Fire");
action native A_VileAttack(sound snd = "vile/stop", int initialdmg = 20, int blastdmg = 70, int blastradius = 70, float thrustfac = 1.0, name damagetype = "Fire", int flags = 0);
action native A_StartFire();
action native A_Fire(float spawnheight = 0);
action native A_FireCrackle();
@ -300,6 +300,7 @@ ACTOR Actor native //: Thinker
action native A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake");
action native A_SetTics(int tics);
action native A_SetDamageType(name damagetype);
action native A_DropItem(class<Actor> item, int dropamount = -1, int chance = 256);
action native A_CheckSightOrRange(float distance, state label);
action native A_CheckRange(float distance, state label);

View File

@ -4,6 +4,9 @@ const int PAF_NOSKULLATTACK = 1;
const int PAF_AIMFACING = 2;
const int PAF_NOTARGET = 4;
// Flags for A_VileAttack
const int VAF_DMGTYPEAPPLYTODIRECT = 1;
// Flags for A_Saw
const int SF_NORANDOM = 1;
const int SF_RANDOMLIGHTMISS = 2;
@ -59,6 +62,7 @@ const int SXF_MULTIPLYSPEED = 8192;
const int SXF_TRANSFERSCALE = 16384;
const int SXF_TRANSFERSPECIAL = 32768;
const int SXF_CLEARCALLERSPECIAL = 65536;
const int SXF_TRANSFERSTENCILCOL = 131072;
// Flags for A_Chase
const int CHF_FASTCHASE = 1;

View File

@ -300,6 +300,7 @@ ACTOR PowerDrain : Powerup native
ACTOR PowerRegeneration : Powerup native
{
Powerup.Duration -120
Powerup.Strength 5
}
ACTOR PowerHighJump : Powerup native {}

View File

@ -24,6 +24,7 @@ Actor PlayerPawn : Actor native
Player.GruntSpeed 12
Player.FallingScreamSpeed 35,40
Player.ViewHeight 41
Player.UseRange 64
Player.ForwardMove 1,1
Player.SideMove 1,1
Player.ColorRange 0,0
@ -31,6 +32,7 @@ Actor PlayerPawn : Actor native
Player.DamageScreenColor "ff 00 00"
Player.MugShotMaxHealth 0
Player.FlechetteType "ArtiPoisonBag3"
Player.AirCapacity 1
Obituary "$OB_MPDEFAULT"
}

View File

@ -20,6 +20,7 @@ ACTOR AlienSpectre1 : SpectralMonster 129
PainSound "alienspectre/pain"
DeathSound "alienspectre/death"
ActiveSound "alienspectre/active"
Obituary "$OB_ALIENSPECTRE"
+NOGRAVITY
+FLOAT
+SHADOW

View File

@ -353,3 +353,26 @@ F481922F4881F74760F3C0437FD5EDD0 // map03
// make the blue key spawn above the 3D floor
setthingz 918 296
}
64B6CE3CB7349B6F6B1A885C449ACB96 // Super Sonic Doom, map31
{
// During the end-of-level tally, both PROP_FROZEN and PROP_TOTALLYFROZEN
// are set, but only PROP_TOTALLYFROZEN is cleared, so PROP_FROZEN is
// still set when returning to the origin map.
linkfrozenprops
}
D62DCA9EC226DE49108D5DD9271F7631 // Cheogsh 2 map04
{
// Stuff in megasphere cage is positioned too low
setthingz 1640 528
setthingz 1641 528
setthingz 1642 528
setthingz 1643 528
setthingz 1644 528
setthingz 1645 528
setthingz 1646 528
setthingz 1647 528
setthingz 1648 528
setthingz 1649 528
}

View File

@ -112,6 +112,7 @@ PD_YELLOWCO = "You need a yellow card to activate this object";
PD_BLUESO = "You need a blue skull to activate this object";
PD_REDSO = "You need a red skull to activate this object";
PD_YELLOWSO = "You need a yellow skull to activate this object";
NEWSAVE = "<New Save Game>";
GGSAVED = "game saved.";
HUSTR_MSGU = "[Message unsent]";
PICKUP_PISTOL_DROPPED = "Picked up a pistol.";
@ -735,7 +736,7 @@ OB_MACIL = "%o should have never rebelled against Macil.";
OB_REBEL = "%o was gunned down by a Rebel.";
OB_BEGGAR = "%o was beaten to death by the poor.";
OB_PEASANT = "%o should have never picked a fight with a civilian.";
OB_ALIENSPECTE = "%o was struck down by the Spectre.";
OB_ALIENSPECTRE = "%o was struck down by the Spectre.";
OB_ENTITY = "%o felt the wrath of The One God.";
OB_LOREMASTER = "%o couldn't escape from the Lore Master's grasp.";
OB_PROGRAMMER = "%o was deleted by the Programmer.";
@ -1614,6 +1615,10 @@ MNU_EPISODE = "Select Episode";
WI_FINISHED = "finished";
WI_ENTERING = "Now entering:";
AM_MONSTERS = "Monsters:";
AM_SECRETS = "Secrets:";
AM_ITEMS = "Items:";
// Bloodbath announcer
BBA_BONED = "%k boned %o like a fish";

View File

@ -779,7 +779,7 @@ OB_MACIL = "%o n'aurait jamais du se rebelle contre Macil.";
OB_REBEL = "%o a ete abbatu par un Rebel.";
OB_BEGGAR = "%o a ete battu a mort par un pauvre.";
OB_PEASANT = "%o n'aurait jamais du chercher la bagarre a un civil.";
OB_ALIENSPECTE = "%o a ete terrasse par le Spectre.";
OB_ALIENSPECTRE = "%o a ete terrasse par le Spectre.";
OB_ENTITY = "%o a senti le courroux du dieu unique.";
OB_LOREMASTER = "%o n'a pu echapper a l'emprise du Maitre des Traditions.";
OB_PROGRAMMER = "%o a ete efface par le Programmer.";

View File

@ -712,7 +712,7 @@ OB_MACIL = "%o should have never rebelled against Macil.";
OB_REBEL = "%o was gunned down by a Rebel.";
OB_BEGGAR = "%o was beaten to death by the poor.";
OB_PEASANT = "%o should have never picked a fight with a civilian.";
OB_ALIENSPECTE = "%o was struck down by the Spectre.";
OB_ALIENSPECTRE = "%o was struck down by the Spectre.";
OB_ENTITY = "%o felt the wrath of The One God.";
OB_LOREMASTER = "%o couldn't escape from the Lore Master's grasp.";
OB_PROGRAMMER = "%o was deleted by the Programmer.";

View File

@ -912,6 +912,14 @@ OptionValue MaplabelTypes
2, "Not for hubs"
}
OptionValue STSTypes
{
0, "Off"
1, "Front"
2, "Animated"
3, "Rotated"
}
OptionMenu AutomapOptions
{
Title "AUTOMAP OPTIONS"
@ -934,6 +942,7 @@ OptionMenu AutomapOptions
Option "Draw map background", "am_drawmapback", "OnOff"
Option "Show keys (cheat)", "am_showkeys", "OnOff"
Option "Show trigger lines", "am_showtriggerlines", "OnOff"
Option "Show things as sprites", "am_showthingsprites", "STSTypes"
}
//-------------------------------------------------------------------------------------------
@ -1001,8 +1010,11 @@ OptionMenu MapColorMenu
StaticText "Overlay Mode", 1
ColorPicker "You", "am_ovyourcolor"
ColorPicker "1-sided walls", "am_ovwallcolor"
ColorPicker "2-sided walls", "am_ovotherwallscolor"
ColorPicker "2-sided walls with different floors", "am_ovfdwallcolor"
ColorPicker "2-sided walls with different ceilings", "am_ovcdwallcolor"
ColorPicker "2-sided walls with 3D floors", "am_ovefwallcolor"
ColorPicker "Not-yet-seen walls", "am_ovunseencolor"
ColorPicker "Locked doors", "am_ovotherwallscolor"
ColorPicker "Teleporter", "am_ovtelecolor"
ColorPicker "Secret sector", "am_ovsecretsectorcolor"
ColorPicker "Special trigger lines", "am_ovspecialwallcolor"