This commit is contained in:
Christoph Oelckers 2015-03-31 18:25:31 +02:00
commit 6eb4e2a224
38 changed files with 585 additions and 400 deletions

View file

@ -1,6 +1,15 @@
cmake_minimum_required( VERSION 2.4 ) cmake_minimum_required( VERSION 2.4 )
project(GZDoom) project(GZDoom)
if( COMMAND cmake_policy )
if( POLICY CMP0011 )
cmake_policy( SET CMP0011 NEW )
endif( POLICY CMP0011 )
if( POLICY CMP0054 )
cmake_policy( SET CMP0054 NEW )
endif( POLICY CMP0054 )
endif( COMMAND cmake_policy )
list( APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ) list( APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} )
include( CreateLaunchers ) include( CreateLaunchers )
include( FindPackageHandleStandardArgs ) include( FindPackageHandleStandardArgs )
@ -26,8 +35,6 @@ endif(CMAKE_CROSSCOMPILING)
# Simplify pk3 building, add_pk3(filename srcdirectory) # Simplify pk3 building, add_pk3(filename srcdirectory)
function( add_pk3 PK3_NAME PK3_DIR ) function( add_pk3 PK3_NAME PK3_DIR )
get_target_property(ZIPDIR_EXE zipdir LOCATION)
# Generate target name. Just use "pk3" for main pk3 target. # Generate target name. Just use "pk3" for main pk3 target.
string( REPLACE "." "_" PK3_TARGET ${PK3_NAME} ) string( REPLACE "." "_" PK3_TARGET ${PK3_NAME} )
if( ${PK3_TARGET} STREQUAL "zdoom_pk3" ) if( ${PK3_TARGET} STREQUAL "zdoom_pk3" )
@ -36,20 +43,22 @@ function( add_pk3 PK3_NAME PK3_DIR )
if( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) if( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE )
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} COMMAND zipdir -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $<TARGET_FILE_DIR:zdoom>/${PK3_NAME} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $<TARGET_FILE_DIR:zdoom>/${PK3_NAME}
DEPENDS zipdir ) DEPENDS zipdir )
else( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) else( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE )
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} COMMAND zipdir -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
DEPENDS zipdir ) DEPENDS zipdir )
endif( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) endif( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE )
# Touch the zipdir executable here so that the pk3s are forced to rebuild if( NOT NO_GENERATOR_EXPRESSIONS )
# each time since their dependecy has "changed." # Touch the zipdir executable here so that the pk3s are forced to
add_custom_target( ${PK3_TARGET} ALL # rebuild each time since their dependecy has "changed."
COMMAND ${CMAKE_COMMAND} -E touch ${ZIPDIR_EXE} add_custom_target( ${PK3_TARGET} ALL
DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ) COMMAND ${CMAKE_COMMAND} -E touch $<TARGET_FILE:zipdir>
DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} )
endif( NOT NO_GENERATOR_EXPRESSIONS )
endfunction( add_pk3 ) endfunction( add_pk3 )
# Macro for building libraries without debugging information # Macro for building libraries without debugging information

View file

@ -44,6 +44,10 @@ if(__create_launchers)
endif() endif()
set(__create_launchers YES) set(__create_launchers YES)
if( POLICY CMP0026 )
cmake_policy( SET CMP0026 OLD )
endif( POLICY CMP0026 )
include(CleanDirectoryList) include(CleanDirectoryList)
# We must run the following at "include" time, not at function call time, # We must run the following at "include" time, not at function call time,
@ -184,7 +188,7 @@ macro(_launcher_process_args)
set(USERFILE_ENV_COMMANDS) set(USERFILE_ENV_COMMANDS)
foreach(_arg "${RUNTIME_LIBRARIES_ENVIRONMENT}" ${ENVIRONMENT}) foreach(_arg "${RUNTIME_LIBRARIES_ENVIRONMENT}" ${ENVIRONMENT})
string(CONFIGURE string(CONFIGURE
"@USERFILE_ENVIRONMENT@@LAUNCHER_LINESEP@@_arg@" "${USERFILE_ENVIRONMENT}${LAUNCHER_LINESEP}${_arg}"
USERFILE_ENVIRONMENT USERFILE_ENVIRONMENT
@ONLY) @ONLY)
string(CONFIGURE string(CONFIGURE

View file

@ -19,18 +19,16 @@ if( NOT MSVC AND NOT APPLE )
if( NOT CMAKE_CROSSCOMPILING ) if( NOT CMAKE_CROSSCOMPILING )
add_executable( arithchk arithchk.c ) add_executable( arithchk arithchk.c )
endif( NOT CMAKE_CROSSCOMPILING ) endif( NOT CMAKE_CROSSCOMPILING )
get_target_property( ARITHCHK_EXE arithchk LOCATION )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/arith.h add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/arith.h
COMMAND ${ARITHCHK_EXE} >${CMAKE_CURRENT_BINARY_DIR}/arith.h COMMAND arithchk >${CMAKE_CURRENT_BINARY_DIR}/arith.h
DEPENDS arithchk ) DEPENDS arithchk )
if( NOT CMAKE_CROSSCOMPILING ) if( NOT CMAKE_CROSSCOMPILING )
add_executable( qnan qnan.c arith.h ) add_executable( qnan qnan.c arith.h )
set( CROSS_EXPORTS ${CROSS_EXPORTS} arithchk qnan PARENT_SCOPE ) set( CROSS_EXPORTS ${CROSS_EXPORTS} arithchk qnan PARENT_SCOPE )
endif( NOT CMAKE_CROSSCOMPILING ) endif( NOT CMAKE_CROSSCOMPILING )
get_target_property( QNAN_EXE qnan LOCATION )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h
COMMAND ${QNAN_EXE} >${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h COMMAND qnan >${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h
DEPENDS qnan ) DEPENDS qnan )
set( GEN_FP_FILES arith.h gd_qnan.h ) set( GEN_FP_FILES arith.h gd_qnan.h )
@ -44,7 +42,4 @@ add_library( gdtoa
misc.c misc.c
) )
target_link_libraries( gdtoa ) target_link_libraries( gdtoa )
if( GEN_FP_DEPS )
add_dependencies( gdtoa ${GEN_FP_DEPS} )
endif( GEN_FP_DEPS )

View file

@ -522,10 +522,8 @@ endif( BACKPATCH )
# Update gitinfo.h # Update gitinfo.h
get_target_property( UPDATEREVISION_EXE updaterevision LOCATION )
add_custom_target( revision_check ALL add_custom_target( revision_check ALL
COMMAND ${UPDATEREVISION_EXE} src/gitinfo.h COMMAND updaterevision src/gitinfo.h
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS updaterevision ) DEPENDS updaterevision )
@ -651,17 +649,14 @@ else( NO_ASM )
endif( X64 ) endif( X64 )
endif( NO_ASM ) endif( NO_ASM )
get_target_property( LEMON_EXE lemon LOCATION )
get_target_property( RE2C_EXE re2c LOCATION )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.h add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.h
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y . COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y .
COMMAND ${LEMON_EXE} xlat_parser.y COMMAND lemon xlat_parser.y
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y ) DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h
COMMAND ${RE2C_EXE} --no-generation-date -s -o ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h ${CMAKE_CURRENT_SOURCE_DIR}/sc_man_scanner.re COMMAND re2c --no-generation-date -s -o ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h ${CMAKE_CURRENT_SOURCE_DIR}/sc_man_scanner.re
DEPENDS re2c ${CMAKE_CURRENT_SOURCE_DIR}/sc_man_scanner.re ) DEPENDS re2c ${CMAKE_CURRENT_SOURCE_DIR}/sc_man_scanner.re )
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} )

View file

@ -130,7 +130,7 @@ static const FBinding DefBindings[] =
static const FBinding DefRavenBindings[] = static const FBinding DefRavenBindings[] =
{ {
{ "pgup", "+moveup" }, { "pgup", "+moveup" },
{ "insert", "+movedown" }, { "ins", "+movedown" },
{ "home", "land" }, { "home", "land" },
{ "pgdn", "+lookup" }, { "pgdn", "+lookup" },
{ "del", "+lookdown" }, { "del", "+lookdown" },

View file

@ -889,21 +889,42 @@ CCMD(info)
"the NOBLOCKMAP flag or have height/radius of 0.\n"); "the NOBLOCKMAP flag or have height/radius of 0.\n");
} }
//----------------------------------------------------------------------------- typedef bool (*ActorTypeChecker) (AActor *);
//
//
//
//-----------------------------------------------------------------------------
CCMD(monster)
{
AActor * mo;
if (CheckCheatmode ()) return; static bool IsActorAMonster(AActor *mo)
{
return mo->flags3&MF3_ISMONSTER && !(mo->flags&MF_CORPSE) && !(mo->flags&MF_FRIENDLY);
}
static bool IsActorAnItem(AActor *mo)
{
return mo->IsKindOf(RUNTIME_CLASS(AInventory)) && mo->flags&MF_SPECIAL;
}
static bool IsActorACountItem(AActor *mo)
{
return mo->IsKindOf(RUNTIME_CLASS(AInventory)) && mo->flags&MF_SPECIAL && mo->flags&MF_COUNTITEM;
}
static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const char *FilterName)
{
AActor *mo;
const PClass *FilterClass = NULL;
if (FilterName != NULL)
{
FilterClass = PClass::FindClass(FilterName);
if (FilterClass == NULL || FilterClass->ActorInfo == NULL)
{
Printf("%s is not an actor class.\n", FilterName);
return;
}
}
TThinkerIterator<AActor> it; TThinkerIterator<AActor> it;
while ( (mo = it.Next()) ) while ( (mo = it.Next()) )
{ {
if (mo->flags3&MF3_ISMONSTER && !(mo->flags&MF_CORPSE) && !(mo->flags&MF_FRIENDLY)) if ((FilterClass == NULL || mo->IsA(FilterClass)) && IsActorType(mo))
{ {
Printf ("%s at (%d,%d,%d)\n", Printf ("%s at (%d,%d,%d)\n",
mo->GetClass()->TypeName.GetChars(), mo->GetClass()->TypeName.GetChars(),
@ -912,6 +933,18 @@ CCMD(monster)
} }
} }
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
CCMD(monster)
{
if (CheckCheatmode ()) return;
PrintFilteredActorList(IsActorAMonster, argv.argc() > 1 ? argv[1] : NULL);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// //
@ -919,20 +952,21 @@ CCMD(monster)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
CCMD(items) CCMD(items)
{ {
AActor * mo;
if (CheckCheatmode ()) return; if (CheckCheatmode ()) return;
TThinkerIterator<AActor> it;
while ( (mo = it.Next()) ) PrintFilteredActorList(IsActorAnItem, argv.argc() > 1 ? argv[1] : NULL);
{ }
if (mo->IsKindOf(RUNTIME_CLASS(AInventory)) && mo->flags&MF_SPECIAL)
{ //-----------------------------------------------------------------------------
Printf ("%s at (%d,%d,%d)\n", //
mo->GetClass()->TypeName.GetChars(), //
mo->x >> FRACBITS, mo->y >> FRACBITS, mo->z >> FRACBITS); //
} //-----------------------------------------------------------------------------
} CCMD(countitems)
{
if (CheckCheatmode ()) return;
PrintFilteredActorList(IsActorACountItem, argv.argc() > 1 ? argv[1] : NULL);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -595,12 +595,13 @@ CCMD (mapchecksum)
else else
{ {
map->GetChecksum(cksum); map->GetChecksum(cksum);
const char *wadname = Wads.GetWadName(Wads.GetLumpFile(map->lumpnum));
delete map; delete map;
for (size_t j = 0; j < sizeof(cksum); ++j) for (size_t j = 0; j < sizeof(cksum); ++j)
{ {
Printf("%02X", cksum[j]); Printf("%02X", cksum[j]);
} }
Printf(" // %s\n", argv[i]); Printf(" // %s %s\n", wadname, argv[i]);
} }
} }
} }

View file

@ -214,6 +214,7 @@ bool autostart;
FString StoredWarp; FString StoredWarp;
bool advancedemo; bool advancedemo;
FILE *debugfile; FILE *debugfile;
FILE *hashfile;
event_t events[MAXEVENTS]; event_t events[MAXEVENTS];
int eventhead; int eventhead;
int eventtail; int eventtail;
@ -2220,6 +2221,26 @@ void D_DoomMain (void)
execLogfile(logfile); execLogfile(logfile);
} }
if (Args->CheckParm("-hashfiles"))
{
const char *filename = "fileinfo.txt";
Printf("Hashing loaded content to: %s\n", filename);
hashfile = fopen(filename, "w");
if (hashfile)
{
fprintf(hashfile, "%s version %s (%s)\n", GAMENAME, GetVersionString(), GetGitHash());
#ifdef __VERSION__
fprintf(hashfile, "Compiler version: %s\n", __VERSION__);
#endif
fprintf(hashfile, "Command line:");
for (int i = 0; i < Args->NumArgs(); ++i)
{
fprintf(hashfile, " %s", Args->GetArg(i));
}
fprintf(hashfile, "\n");
}
}
D_DoomInit(); D_DoomInit();
PClass::StaticInit (); PClass::StaticInit ();
atterm(FinalGC); atterm(FinalGC);
@ -2289,6 +2310,11 @@ void D_DoomMain (void)
pwads.Clear(); pwads.Clear();
pwads.ShrinkToFit(); pwads.ShrinkToFit();
if (hashfile)
{
Printf("Notice: File hashing is incredibly verbose. Expect loading files to take much longer then usual.\n");
}
Printf ("W_Init: Init WADfiles.\n"); Printf ("W_Init: Init WADfiles.\n");
Wads.InitMultipleFiles (allwads); Wads.InitMultipleFiles (allwads);
allwads.Clear(); allwads.Clear();

View file

@ -443,10 +443,15 @@ public:
FName LastDamageType; // [RH] For damage-specific pain and death sounds FName LastDamageType; // [RH] For damage-specific pain and death sounds
//Added by MC: TObjPtr<AActor> MUSINFOactor; // For MUSINFO purposes
TObjPtr<DBot> Bot; SBYTE MUSINFOtics;
bool settings_controller; // Player can control game settings. bool settings_controller; // Player can control game settings.
SBYTE crouching;
SBYTE crouchdir;
//Added by MC:
TObjPtr<DBot> Bot;
float BlendR; // [RH] Final blending values float BlendR; // [RH] Final blending values
float BlendG; float BlendG;
@ -458,8 +463,6 @@ public:
int MinPitch; // Viewpitch limits (negative is up, positive is down) int MinPitch; // Viewpitch limits (negative is up, positive is down)
int MaxPitch; int MaxPitch;
SBYTE crouching;
SBYTE crouchdir;
fixed_t crouchfactor; fixed_t crouchfactor;
fixed_t crouchoffset; fixed_t crouchoffset;
fixed_t crouchviewdelta; fixed_t crouchviewdelta;

View file

@ -172,6 +172,7 @@ extern bool playeringame[/*MAXPLAYERS*/];
// File handling stuff. // File handling stuff.
extern FILE* debugfile; extern FILE* debugfile;
extern FILE* hashfile;
// if true, load all graphics at level load // if true, load all graphics at level load
extern bool precache; extern bool precache;

View file

@ -1420,7 +1420,7 @@ void FParser::SF_PointToDist(void)
double y = floatvalue(t_argv[3]) - floatvalue(t_argv[1]); double y = floatvalue(t_argv[3]) - floatvalue(t_argv[1]);
t_return.type = svt_fixed; t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(sqrt(x*x+y*y)*65536.f); t_return.value.f = FLOAT2FIXED(sqrt(x*x+y*y));
} }
} }

View file

@ -584,7 +584,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
int j; int j;
int damage; int damage;
angle_t an; angle_t an;
AActor *thingToHit;
AActor *linetarget; AActor *linetarget;
ACTION_PARAM_START(7); ACTION_PARAM_START(7);
@ -615,42 +614,42 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
// self->target is the originator (player) of the missile // self->target is the originator (player) of the missile
P_AimLineAttack(self->target, an, distance, &linetarget, vrange); P_AimLineAttack(self->target, an, distance, &linetarget, vrange);
if (!linetarget) if (linetarget != NULL)
continue;
AActor *spray = Spawn(spraytype, linetarget->x, linetarget->y,
linetarget->z + (linetarget->height >> 2), ALLOW_REPLACE);
if (spray)
{ {
if (spray->flags6 & MF6_MTHRUSPECIES && spray->GetSpecies() == linetarget->GetSpecies()) AActor *spray = Spawn(spraytype, linetarget->x, linetarget->y,
linetarget->z + (linetarget->height >> 2), ALLOW_REPLACE);
int dmgFlags = 0;
FName dmgType = NAME_BFGSplash;
if (spray != NULL)
{ {
spray->Destroy(); // [MC] Remove it because technically, the spray isn't trying to "hit" them. if (spray->flags6 & MF6_MTHRUSPECIES && spray->GetSpecies() == linetarget->GetSpecies())
continue; {
spray->Destroy(); // [MC] Remove it because technically, the spray isn't trying to "hit" them.
continue;
}
if (spray->flags5 & MF5_PUFFGETSOWNER) spray->target = self->target;
if (spray->flags3 & MF3_FOILINVUL) dmgFlags |= DMG_FOILINVUL;
if (spray->flags7 & MF7_FOILBUDDHA) dmgFlags |= DMG_FOILBUDDHA;
dmgType = spray->DamageType;
} }
if (spray->flags5 & MF5_PUFFGETSOWNER)
spray->target = self->target;
}
if (defdamage == 0) if (defdamage == 0)
{ {
damage = 0; damage = 0;
for (j = 0; j < damagecnt; ++j) for (j = 0; j < damagecnt; ++j)
damage += (pr_bfgspray() & 7) + 1; damage += (pr_bfgspray() & 7) + 1;
} }
else else
{ {
// if this is used, damagecnt will be ignored // if this is used, damagecnt will be ignored
damage = defdamage; damage = defdamage;
} }
int dmgFlagPass = 0; int newdam = P_DamageMobj(linetarget, self->target, self->target, damage, dmgType, dmgFlags);
dmgFlagPass += (spray != NULL && (spray->flags3 & MF3_FOILINVUL)) ? DMG_FOILINVUL : 0; //[MC]Because the original foilinvul wasn't working. P_TraceBleed(newdam > 0 ? newdam : damage, linetarget, self->target);
dmgFlagPass += (spray != NULL && (spray->flags7 & MF7_FOILBUDDHA)) ? DMG_FOILBUDDHA : 0; }
thingToHit = linetarget;
int newdam = P_DamageMobj (thingToHit, self->target, self->target, damage, spray != NULL? FName(spray->DamageType) : FName(NAME_BFGSplash),
dmgFlagPass);
P_TraceBleed (newdam > 0 ? newdam : damage, thingToHit, self->target);
} }
} }

View file

@ -83,7 +83,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
{ {
pmo->health = player->health = newLife; pmo->health = player->health = newLife;
} }
P_SetPsprite (player, ps_weapon, weapon->FindState ("Drain")); if (weapon != NULL)
{
FState * newstate = weapon->FindState("Drain");
if (newstate != NULL) P_SetPsprite(player, ps_weapon, newstate);
}
} }
if (weapon != NULL) if (weapon != NULL)
{ {

View file

@ -1459,7 +1459,9 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
if (SaveVersion >= 3313) if (SaveVersion >= 3313)
{ {
arc << level.nextmusic; // This is a player property now
int nextmusic;
arc << nextmusic;
} }
// Hub transitions must keep the current total time // Hub transitions must keep the current total time

View file

@ -336,6 +336,7 @@ struct level_info_t
TArray<FSpecialAction> specialactions; TArray<FSpecialAction> specialactions;
TArray<FSoundID> PrecacheSounds; TArray<FSoundID> PrecacheSounds;
TArray<FTextureID> PrecacheTextures;
level_info_t() level_info_t()
{ {
@ -412,7 +413,6 @@ struct FLevelLocals
int musicorder; int musicorder;
int cdtrack; int cdtrack;
unsigned int cdid; unsigned int cdid;
int nextmusic; // For MUSINFO purposes
FTextureID skytexture1; FTextureID skytexture1;
FTextureID skytexture2; FTextureID skytexture2;

View file

@ -1065,6 +1065,25 @@ DEFINE_MAP_OPTION(PrecacheSounds, true)
} while (parse.sc.CheckString(",")); } while (parse.sc.CheckString(","));
} }
DEFINE_MAP_OPTION(PrecacheTextures, true)
{
parse.ParseAssign();
do
{
parse.sc.MustGetString();
FTextureID tex = TexMan.CheckForTexture(parse.sc.String, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_ReturnFirst);
if (!tex.isValid())
{
parse.sc.ScriptMessage("Unknown texture \"%s\"", parse.sc.String);
}
else
{
info->PrecacheTextures.Push(tex);
}
} while (parse.sc.CheckString(","));
}
DEFINE_MAP_OPTION(redirect, true) DEFINE_MAP_OPTION(redirect, true)
{ {
parse.ParseAssign(); parse.ParseAssign();

View file

@ -138,7 +138,13 @@ FGameConfigFile::FGameConfigFile ()
SetValueForKey ("Path", "$PROGDIR", true); SetValueForKey ("Path", "$PROGDIR", true);
#else #else
SetValueForKey ("Path", "~/" GAME_DIR, true); SetValueForKey ("Path", "~/" GAME_DIR, true);
SetValueForKey ("Path", SHARE_DIR, true); // Arch Linux likes them in /usr/share/doom
// Debian likes them in /usr/share/games/doom
// I assume other distributions don't do anything radically different
SetValueForKey ("Path", "/usr/local/share/doom", true);
SetValueForKey ("Path", "/usr/local/share/games/doom", true);
SetValueForKey ("Path", "/usr/share/doom", true);
SetValueForKey ("Path", "/usr/share/games/doom", true);
#endif #endif
} }
@ -166,24 +172,24 @@ FGameConfigFile::FGameConfigFile ()
CreateSectionAtStart("Harmony.Autoload"); CreateSectionAtStart("Harmony.Autoload");
CreateSectionAtStart("UrbanBrawl.Autoload"); CreateSectionAtStart("UrbanBrawl.Autoload");
CreateSectionAtStart("Chex3.Autoload"); CreateSectionAtStart("Chex3.Autoload");
CreateSectionAtStart("Chex1.Autoload"); CreateSectionAtStart("Chex1.Autoload");
CreateSectionAtStart("Chex.Autoload"); CreateSectionAtStart("Chex.Autoload");
CreateSectionAtStart("Strife.Autoload"); CreateSectionAtStart("Strife.Autoload");
CreateSectionAtStart("HexenDK.Autoload"); CreateSectionAtStart("HexenDK.Autoload");
CreateSectionAtStart("Hexen.Autoload"); CreateSectionAtStart("Hexen.Autoload");
CreateSectionAtStart("HereticSR.Autoload"); CreateSectionAtStart("HereticSR.Autoload");
CreateSectionAtStart("Heretic.Autoload"); CreateSectionAtStart("Heretic.Autoload");
CreateSectionAtStart("FreeDM.Autoload"); CreateSectionAtStart("FreeDM.Autoload");
CreateSectionAtStart("Freedoom2.Autoload"); CreateSectionAtStart("Freedoom2.Autoload");
CreateSectionAtStart("Freedoom1.Autoload"); CreateSectionAtStart("Freedoom1.Autoload");
CreateSectionAtStart("Freedoom.Autoload"); CreateSectionAtStart("Freedoom.Autoload");
CreateSectionAtStart("Plutonia.Autoload"); CreateSectionAtStart("Plutonia.Autoload");
CreateSectionAtStart("TNT.Autoload"); CreateSectionAtStart("TNT.Autoload");
CreateSectionAtStart("Doom2BFG.Autoload"); CreateSectionAtStart("Doom2BFG.Autoload");
CreateSectionAtStart("Doom2.Autoload"); CreateSectionAtStart("Doom2.Autoload");
CreateSectionAtStart("DoomBFG.Autoload"); CreateSectionAtStart("DoomBFG.Autoload");
CreateSectionAtStart("DoomU.Autoload"); CreateSectionAtStart("DoomU.Autoload");
CreateSectionAtStart("Doom1.Autoload"); CreateSectionAtStart("Doom1.Autoload");
CreateSectionAtStart("Doom.Autoload"); CreateSectionAtStart("Doom.Autoload");
CreateSectionAtStart("Global.Autoload"); CreateSectionAtStart("Global.Autoload");

View file

@ -4767,25 +4767,19 @@ static void SetActorRoll(AActor *activator, int tid, int angle, bool interpolate
} }
} }
static void SetActorTeleFog(AActor *activator, int tid, FName telefogsrc, FName telefogdest) static void SetActorTeleFog(AActor *activator, int tid, FString telefogsrc, FString telefogdest)
{ {
//Simply put, if it doesn't exist, it won't change. One can use "" in this scenario. // Set the actor's telefog to the specified actor. Handle "" as "don't
const PClass *check; // change" since "None" should work just fine for disabling the fog (given
// that it will resolve to NAME_None which is not a valid actor name).
if (tid == 0) if (tid == 0)
{ {
if (activator != NULL) if (activator != NULL)
{ {
check = PClass::FindClass(telefogsrc); if (telefogsrc.IsNotEmpty())
if (check == NULL || !stricmp(telefogsrc, "none") || !stricmp(telefogsrc, "null")) activator->TeleFogSourceType = PClass::FindClass(telefogsrc);
activator->TeleFogSourceType = NULL; if (telefogdest.IsNotEmpty())
else activator->TeleFogDestType = PClass::FindClass(telefogdest);
activator->TeleFogSourceType = check;
check = PClass::FindClass(telefogdest);
if (check == NULL || !stricmp(telefogdest, "none") || !stricmp(telefogdest, "null"))
activator->TeleFogDestType = NULL;
else
activator->TeleFogDestType = check;
} }
} }
else else
@ -4793,19 +4787,14 @@ static void SetActorTeleFog(AActor *activator, int tid, FName telefogsrc, FName
FActorIterator iterator(tid); FActorIterator iterator(tid);
AActor *actor; AActor *actor;
const PClass * const src = telefogsrc.IsNotEmpty() ? PClass::FindClass(telefogsrc) : NULL;
const PClass * const dest = telefogdest.IsNotEmpty() ? PClass::FindClass(telefogdest) : NULL;
while ((actor = iterator.Next())) while ((actor = iterator.Next()))
{ {
check = PClass::FindClass(telefogsrc); if (telefogsrc.IsNotEmpty())
if (check == NULL || !stricmp(telefogsrc, "none") || !stricmp(telefogsrc, "null")) actor->TeleFogSourceType = src;
actor->TeleFogSourceType = NULL; if (telefogdest.IsNotEmpty())
else actor->TeleFogDestType = dest;
actor->TeleFogSourceType = check;
check = PClass::FindClass(telefogdest);
if (check == NULL || !stricmp(telefogdest, "none") || !stricmp(telefogdest, "null"))
actor->TeleFogDestType = NULL;
else
actor->TeleFogDestType = check;
} }
} }
} }
@ -5700,10 +5689,10 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
case ACSF_QuakeEx: case ACSF_QuakeEx:
{ {
return P_StartQuakeXYZ(activator, args[0], args[1], args[2], args[3], args[4], args[5], args[6], FBehavior::StaticLookupString(args[7]), return P_StartQuakeXYZ(activator, args[0], args[1], args[2], args[3], args[4], args[5], args[6], FBehavior::StaticLookupString(args[7]),
argCount > 8 && args[8] ? args[8] : 0, argCount > 8 ? args[8] : 0,
argCount > 9 && args[9] ? args[9] : 1, argCount > 9 ? FIXED2DBL(args[9]) : 1.0,
argCount > 10 && args[10] ? args[10] : 1, argCount > 10 ? FIXED2DBL(args[10]) : 1.0,
argCount > 11 && args[11] ? args[11] : 1 ); argCount > 11 ? FIXED2DBL(args[11]) : 1.0 );
} }
case ACSF_SetLineActivation: case ACSF_SetLineActivation:

View file

@ -44,6 +44,7 @@
#include "thingdef/thingdef.h" #include "thingdef/thingdef.h"
#include "d_dehacked.h" #include "d_dehacked.h"
#include "g_level.h" #include "g_level.h"
#include "r_data/r_translate.h"
#include "teaminfo.h" #include "teaminfo.h"
#include "gi.h" #include "gi.h"
@ -2615,7 +2616,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
S_Sound(corpsehit, CHAN_BODY, "vile/raise", 1, ATTN_IDLE); S_Sound(corpsehit, CHAN_BODY, "vile/raise", 1, ATTN_IDLE);
info = corpsehit->GetDefault(); info = corpsehit->GetDefault();
if (corpsehit->state == corpsehit->FindState(NAME_GenericCrush)) if (GetTranslationType(corpsehit->Translation) == TRANSLATION_Blood)
{ {
corpsehit->Translation = info->Translation; // Clean up bloodcolor translation from crushed corpses corpsehit->Translation = info->Translation; // Clean up bloodcolor translation from crushed corpses
} }
@ -3203,10 +3204,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Die)
ACTION_PARAM_START(1); ACTION_PARAM_START(1);
ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_NAME(damagetype, 0);
if (self->flags & MF_MISSILE) P_DamageMobj (self, NULL, NULL, self->health, damagetype, DMG_FORCED);
P_ExplodeMissile(self, NULL, NULL);
else
P_DamageMobj (self, NULL, NULL, self->health, damagetype, DMG_FORCED);
} }
// //

View file

@ -925,9 +925,9 @@ static inline bool MustForcePain(AActor *target, AActor *inflictor)
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS)); (inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS));
} }
static inline bool isFakePain(AActor *target, AActor *inflictor) static inline bool isFakePain(AActor *target, AActor *inflictor, int damage)
{ {
return ((target->flags7 & MF7_ALLOWPAIN) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN))); return ((target->flags7 & MF7_ALLOWPAIN && damage > 0) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN)));
} }
@ -956,7 +956,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
} }
//Rather than unnecessarily call the function over and over again, let's be a little more efficient. //Rather than unnecessarily call the function over and over again, let's be a little more efficient.
fakedPain = (isFakePain(target, inflictor)); fakedPain = (isFakePain(target, inflictor, damage));
forcedPain = (MustForcePain(target, inflictor)); forcedPain = (MustForcePain(target, inflictor));
// Spectral targets only take damage from spectral projectiles. // Spectral targets only take damage from spectral projectiles.
@ -989,9 +989,11 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
{ {
if (fakedPain) if (fakedPain)
{ {
invulpain = true; //This returns -1 later. // big mess here: What do we use for the pain threshold?
fakeDamage = damage; // We cannot run the various damage filters below so for consistency it needs to be 0.
goto fakepain; //The label is above the massive pile of checks. damage = 0;
invulpain = true;
goto fakepain;
} }
else else
return -1; return -1;
@ -1010,12 +1012,6 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
} }
} }
if ((fakedPain) && (damage < TELEFRAG_DAMAGE))
{
//Intentionally do not jump to fakepain because the damage hasn't been dished out yet.
//Once it's dished out, THEN we can disregard damage factors affecting pain chances.
fakeDamage = damage;
}
if (inflictor != NULL) if (inflictor != NULL)
{ {
@ -1035,113 +1031,101 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
{ {
target->velx = target->vely = target->velz = 0; target->velx = target->vely = target->velz = 0;
} }
if (!(flags & DMG_FORCED)) // DMG_FORCED skips all special damage checks if (!(flags & DMG_FORCED)) // DMG_FORCED skips all special damage checks, TELEFRAG_DAMAGE may not be reduced at all
{ {
if (target->flags2 & MF2_DORMANT) if (target->flags2 & MF2_DORMANT)
{ {
// Invulnerable, and won't wake up // Invulnerable, and won't wake up
return -1; return -1;
} }
if (damage < TELEFRAG_DAMAGE) // TELEFRAG_DAMAGE may not be reduced at all or it may not guarantee its effect.
player = target->player;
if (player && damage > 1 && damage < TELEFRAG_DAMAGE)
{ {
// Take half damage in trainer mode player = target->player;
damage = FixedMul(damage, G_SkillProperty(SKILLP_DamageFactor)); if (player && damage > 1)
}
// Special damage types
if (inflictor)
{
if (inflictor->flags4 & MF4_SPECTRAL)
{ {
if (player != NULL) // Take half damage in trainer mode
damage = FixedMul(damage, G_SkillProperty(SKILLP_DamageFactor));
}
// Special damage types
if (inflictor)
{
if (inflictor->flags4 & MF4_SPECTRAL)
{ {
if (!deathmatch && inflictor->FriendPlayer > 0) if (player != NULL)
return -1; {
if (!deathmatch && inflictor->FriendPlayer > 0)
return -1;
}
else if (target->flags4 & MF4_SPECTRAL)
{
if (inflictor->FriendPlayer == 0 && !target->IsHostile(inflictor))
return -1;
}
} }
else if (target->flags4 & MF4_SPECTRAL)
damage = inflictor->DoSpecialDamage(target, damage, mod);
if (damage < 0)
{ {
if (inflictor->FriendPlayer == 0 && !target->IsHostile(inflictor)) return -1;
return -1;
} }
} }
if (damage > 0)
damage = inflictor->DoSpecialDamage (target, damage, mod);
if ((damage == -1) && (target->player == NULL)) //This isn't meant for the player.
{
if (fakedPain) //Hold off ending the function before we can deal the pain chances.
goto fakepain;
return -1;
}
}
// Handle active damage modifiers (e.g. PowerDamage)
if (source != NULL)
{
int olddam = damage; int olddam = damage;
if (source->Inventory != NULL) if (damage > 0 && source != NULL)
{ {
source->Inventory->ModifyDamage(olddam, mod, damage, false); damage = FixedMul(damage, source->DamageMultiply);
// Handle active damage modifiers (e.g. PowerDamage)
if (damage > 0 && source->Inventory != NULL)
{
source->Inventory->ModifyDamage(damage, mod, damage, false);
}
} }
damage = FixedMul(damage, source->DamageMultiply); // Handle passive damage modifiers (e.g. PowerProtection), provided they are not afflicted with protection penetrating powers.
if (damage > 0 && (target->Inventory != NULL) && !(flags & DMG_NO_PROTECT))
if (((source->flags7 & MF7_CAUSEPAIN) && (fakeDamage <= 0)) || (olddam != damage && damage <= 0))
{ // Still allow FORCEPAIN
if (forcedPain)
goto dopain;
else if (fakedPain)
goto fakepain;
return -1;
}
}
// Handle passive damage modifiers (e.g. PowerProtection), provided they are not afflicted with protection penetrating powers.
if ((target->Inventory != NULL) && !(flags & DMG_NO_PROTECT))
{
int olddam = damage;
target->Inventory->ModifyDamage(olddam, mod, damage, true);
if ((olddam != damage && damage <= 0) && target->player == NULL)
{ // Still allow FORCEPAIN and make sure we're still passing along fake damage to hit enemies for their pain states.
if (forcedPain)
goto dopain;
else if (fakedPain)
goto fakepain;
return -1;
}
}
if (!(flags & DMG_NO_FACTOR))
{
damage = FixedMul(damage, target->DamageFactor);
if (damage > 0)
{ {
damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, mod, target->GetClass()->ActorInfo->DamageFactors); target->Inventory->ModifyDamage(damage, mod, damage, true);
}
if (damage > 0 && !(flags & DMG_NO_FACTOR))
{
damage = FixedMul(damage, target->DamageFactor);
if (damage > 0)
{
damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, mod, target->GetClass()->ActorInfo->DamageFactors);
}
} }
if (damage <= 0 && target->player == NULL)
{ // Still allow FORCEPAIN
if (forcedPain)
goto dopain;
else if (fakedPain)
goto fakepain;
return -1; if (damage >= 0)
{
damage = target->TakeSpecialDamage(inflictor, source, damage, mod);
}
// '<0' is handled below. This only handles the case where damage gets reduced to 0.
if (damage == 0 && olddam > 0)
{
{ // Still allow FORCEPAIN
if (forcedPain)
{
goto dopain;
}
else if (fakedPain)
{
goto fakepain;
}
return -1;
}
} }
} }
if (damage > 0)
damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
} }
if (damage == -1 && target->player == NULL) //Make sure it's not a player, the pain has yet to be processed with cheats. if (damage < 0)
{ {
if (fakedPain) // any negative value means that something in the above chain has cancelled out all damage and all damage effects, including pain.
goto fakepain;
return -1; return -1;
} }
// Push the target unless the source's weapon's kickback is 0. // Push the target unless the source's weapon's kickback is 0.
// (i.e. Gauntlets/Chainsaw) // (i.e. Gauntlets/Chainsaw)
if (!(plrDontThrust) && inflictor && inflictor != target // [RH] Not if hurting own self if (!plrDontThrust && inflictor && inflictor != target // [RH] Not if hurting own self
&& !(target->flags & MF_NOCLIP) && !(target->flags & MF_NOCLIP)
&& !(inflictor->flags2 & MF2_NODMGTHRUST) && !(inflictor->flags2 & MF2_NODMGTHRUST)
&& !(flags & DMG_THRUSTLESS) && !(flags & DMG_THRUSTLESS)
@ -1182,10 +1166,11 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
{ {
fltthrust = clamp((damage * 0.125 * kickback) / target->Mass, 0., fltthrust); fltthrust = clamp((damage * 0.125 * kickback) / target->Mass, 0., fltthrust);
} }
thrust = FLOAT2FIXED(fltthrust); thrust = FLOAT2FIXED(fltthrust);
// Don't apply ultra-small damage thrust.
if (thrust < FRACUNIT / 100) // Don't apply ultra-small damage thrust
thrust = 0; if (thrust < FRACUNIT/100) thrust = 0;
// make fall forwards sometimes // make fall forwards sometimes
if ((damage < 40) && (damage > target->health) if ((damage < 40) && (damage > target->health)
@ -1194,7 +1179,8 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
// [RH] But only if not too fast and not flying // [RH] But only if not too fast and not flying
&& thrust < 10*FRACUNIT && thrust < 10*FRACUNIT
&& !(target->flags & MF_NOGRAVITY) && !(target->flags & MF_NOGRAVITY)
&& (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL))) && (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL))
)
{ {
ang += ANG180; ang += ANG180;
thrust *= 4; thrust *= 4;
@ -1230,8 +1216,22 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
if (damage < TELEFRAG_DAMAGE) if (damage < TELEFRAG_DAMAGE)
{ // Still allow telefragging :-( { // Still allow telefragging :-(
damage = (int)((float)damage * level.teamdamage); damage = (int)((float)damage * level.teamdamage);
if (damage <= 0) if (damage < 0)
{
return damage; return damage;
}
else if (damage == 0)
{
if (forcedPain)
{
goto dopain;
}
else if (fakedPain)
{
goto fakepain;
}
return -1;
}
} }
} }
@ -1268,7 +1268,6 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
else if ((((player->mo->flags7 & MF7_ALLOWPAIN) || (player->mo->flags5 & MF5_NODAMAGE)) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN)))) else if ((((player->mo->flags7 & MF7_ALLOWPAIN) || (player->mo->flags5 & MF5_NODAMAGE)) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN))))
{ {
invulpain = true; invulpain = true;
fakeDamage = damage;
goto fakepain; goto fakepain;
} }
else else
@ -1390,7 +1389,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
if (target->health <= 0) if (target->health <= 0)
{ {
//[MC]Buddha flag for monsters. //[MC]Buddha flag for monsters.
if ((target->flags7 & MF7_BUDDHA) && (damage < TELEFRAG_DAMAGE) && ((inflictor == NULL || !(inflictor->flags3 & MF7_FOILBUDDHA)) && !(flags & DMG_FOILBUDDHA))) if ((target->flags7 & MF7_BUDDHA) && (damage < TELEFRAG_DAMAGE) && ((inflictor == NULL || !(inflictor->flags7 & MF7_FOILBUDDHA)) && !(flags & DMG_FOILBUDDHA)))
{ //FOILBUDDHA or Telefrag damage must kill it. { //FOILBUDDHA or Telefrag damage must kill it.
target->health = 1; target->health = 1;
} }
@ -1451,15 +1450,6 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
fakepain: //Needed so we can skip the rest of the above, but still obey the original rules. fakepain: //Needed so we can skip the rest of the above, but still obey the original rules.
//CAUSEPAIN can always attempt to trigger the chances of pain.
//ALLOWPAIN can do the same, only if the (unfiltered aka fake) damage is greater than 0.
if ((((target->flags7 & MF7_ALLOWPAIN) && (fakeDamage > 0))
|| ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN))))
{
holdDamage = damage; //Store the modified damage away after factors are taken into account.
damage = fakeDamage; //Retrieve the original damage.
}
if (!(target->flags5 & MF5_NOPAIN) && (inflictor == NULL || !(inflictor->flags5 & MF5_PAINLESS)) && if (!(target->flags5 & MF5_NOPAIN) && (inflictor == NULL || !(inflictor->flags5 & MF5_PAINLESS)) &&
(target->player != NULL || !G_SkillProperty(SKILLP_NoPain)) && !(target->flags & MF_SKULLFLY)) (target->player != NULL || !G_SkillProperty(SKILLP_NoPain)) && !(target->flags & MF_SKULLFLY))
{ {
@ -1474,7 +1464,7 @@ fakepain: //Needed so we can skip the rest of the above, but still obey the orig
} }
} }
if ((((damage >= target->PainThreshold)) && (pr_damagemobj() < painchance)) if (((damage >= target->PainThreshold) && (pr_damagemobj() < painchance))
|| (inflictor != NULL && (inflictor->flags6 & MF6_FORCEPAIN))) || (inflictor != NULL && (inflictor->flags6 & MF6_FORCEPAIN)))
{ {
dopain: dopain:
@ -1555,10 +1545,6 @@ dopain:
{ {
return -1; //NOW we return -1! return -1; //NOW we return -1!
} }
else if (fakedPain)
{
return holdDamage; //This is the calculated damage after all is said and done.
}
return damage; return damage;
} }

View file

@ -1288,7 +1288,7 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
// Do damage // Do damage
damage = tm.thing->GetMissileDamage((tm.thing->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1); damage = tm.thing->GetMissileDamage((tm.thing->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1);
if ((damage > 0) || (tm.thing->flags6 & MF6_FORCEPAIN)) if ((damage > 0) || (tm.thing->flags6 & MF6_FORCEPAIN) || (tm.thing->flags7 & MF7_CAUSEPAIN))
{ {
int newdam = P_DamageMobj(thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType); int newdam = P_DamageMobj(thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType);
if (damage > 0) if (damage > 0)
@ -4243,13 +4243,16 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags, hitactor); P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags, hitactor);
} }
if (puffDefaults && puffDefaults->PoisonDamage > 0 && puffDefaults->PoisonDuration != INT_MIN)
{
P_PoisonMobj(hitactor, thepuff ? thepuff : source, source, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod, puffDefaults->PoisonDamageType);
}
int dmgFlagPass = DMG_INFLICTOR_IS_PUFF; int dmgFlagPass = DMG_INFLICTOR_IS_PUFF;
dmgFlagPass += (puffDefaults->flags3 & MF3_FOILINVUL) ? DMG_FOILINVUL : 0; //[MC]Because the original foilinvul check wasn't working. if (puffDefaults != NULL) // is this even possible?
dmgFlagPass += (puffDefaults->flags7 & MF7_FOILBUDDHA) ? DMG_FOILBUDDHA : 0; {
if (puffDefaults->PoisonDamage > 0 && puffDefaults->PoisonDuration != INT_MIN)
{
P_PoisonMobj(hitactor, thepuff ? thepuff : source, source, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod, puffDefaults->PoisonDamageType);
}
if (puffDefaults->flags3 & MF3_FOILINVUL) dmgFlagPass |= DMG_FOILINVUL;
if (puffDefaults->flags7 & MF7_FOILBUDDHA) dmgFlagPass |= DMG_FOILBUDDHA;
}
int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass); int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass);
if (bleed) if (bleed)

View file

@ -4480,7 +4480,8 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
p->mo->ResetAirSupply(false); p->mo->ResetAirSupply(false);
p->Uncrouch(); p->Uncrouch();
p->MinPitch = p->MaxPitch = 0; // will be filled in by PostBeginPlay()/netcode p->MinPitch = p->MaxPitch = 0; // will be filled in by PostBeginPlay()/netcode
p->MUSINFOactor = NULL;
p->MUSINFOtics = -1;
p->velx = p->vely = 0; // killough 10/98: initialize bobbing to 0. p->velx = p->vely = 0; // killough 10/98: initialize bobbing to 0.
@ -6442,7 +6443,8 @@ void PrintMiscActorInfo(AActor *query)
} }
} }
static const char * renderstyles[]= {"None", "Normal", "Fuzzy", "SoulTrans", static const char * renderstyles[]= {"None", "Normal", "Fuzzy", "SoulTrans",
"OptFuzzy", "Stencil", "Translucent", "Add", "Shaded", "TranslucentStencil"}; "OptFuzzy", "Stencil", "Translucent", "Add", "Shaded", "TranslucentStencil",
"Shadow", "Subtract", "AddStencil", "AddShaded"};
Printf("%s @ %p has the following flags:\n flags: %x", query->GetTag(), query, query->flags); Printf("%s @ %p has the following flags:\n flags: %x", query->GetTag(), query, query->flags);
for (flagi = 0; flagi <= 31; flagi++) for (flagi = 0; flagi <= 31; flagi++)

View file

@ -309,7 +309,9 @@ player_t::player_t()
ConversationNPC(0), ConversationNPC(0),
ConversationPC(0), ConversationPC(0),
ConversationNPCAngle(0), ConversationNPCAngle(0),
ConversationFaceTalker(0) ConversationFaceTalker(0),
MUSINFOactor(0),
MUSINFOtics(-1)
{ {
memset (&cmd, 0, sizeof(cmd)); memset (&cmd, 0, sizeof(cmd));
memset (frags, 0, sizeof(frags)); memset (frags, 0, sizeof(frags));
@ -400,6 +402,8 @@ player_t &player_t::operator=(const player_t &p)
ConversationPC = p.ConversationPC; ConversationPC = p.ConversationPC;
ConversationNPCAngle = p.ConversationNPCAngle; ConversationNPCAngle = p.ConversationNPCAngle;
ConversationFaceTalker = p.ConversationFaceTalker; ConversationFaceTalker = p.ConversationFaceTalker;
MUSINFOactor = p.MUSINFOactor;
MUSINFOtics = p.MUSINFOtics;
return *this; return *this;
} }
@ -430,6 +434,7 @@ size_t player_t::FixPointers (const DObject *old, DObject *rep)
if (*&PremorphWeapon == old) PremorphWeapon = static_cast<AWeapon *>(rep), changed++; if (*&PremorphWeapon == old) PremorphWeapon = static_cast<AWeapon *>(rep), changed++;
if (*&ConversationNPC == old) ConversationNPC = replacement, changed++; if (*&ConversationNPC == old) ConversationNPC = replacement, changed++;
if (*&ConversationPC == old) ConversationPC = replacement, changed++; if (*&ConversationPC == old) ConversationPC = replacement, changed++;
if (*&MUSINFOactor == old) MUSINFOactor = replacement, changed++;
return changed; return changed;
} }
@ -443,6 +448,7 @@ size_t player_t::PropagateMark()
GC::Mark(ReadyWeapon); GC::Mark(ReadyWeapon);
GC::Mark(ConversationNPC); GC::Mark(ConversationNPC);
GC::Mark(ConversationPC); GC::Mark(ConversationPC);
GC::Mark(MUSINFOactor);
GC::Mark(PremorphWeapon); GC::Mark(PremorphWeapon);
if (PendingWeapon != WP_NOCHANGE) if (PendingWeapon != WP_NOCHANGE)
{ {
@ -2331,6 +2337,30 @@ void P_PlayerThink (player_t *player)
player->crouchoffset = -FixedMul(player->mo->ViewHeight, (FRACUNIT - player->crouchfactor)); player->crouchoffset = -FixedMul(player->mo->ViewHeight, (FRACUNIT - player->crouchfactor));
// MUSINFO stuff
if (player->MUSINFOtics >= 0 && player->MUSINFOactor != NULL)
{
if (--player->MUSINFOtics < 0)
{
if (player - players == consoleplayer)
{
if (player->MUSINFOactor->args[0] != 0)
{
FName *music = level.info->MusicMap.CheckKey(player->MUSINFOactor->args[0]);
if (music != NULL)
{
S_ChangeMusic(music->GetChars(), player->MUSINFOactor->args[1]);
}
}
else
{
S_ChangeMusic("*");
}
}
DPrintf("MUSINFO change for player %d to %d\n", (int)(player - players), player->MUSINFOactor->args[0]);
}
}
if (player->playerstate == PST_DEAD) if (player->playerstate == PST_DEAD)
{ {
@ -3105,6 +3135,10 @@ void player_t::Serialize (FArchive &arc)
{ {
userinfo.SkinChanged(skinname, CurrentPlayerClass); userinfo.SkinChanged(skinname, CurrentPlayerClass);
} }
if (SaveVersion >= 4522)
{
arc << MUSINFOactor << MUSINFOtics;
}
} }

View file

@ -1359,6 +1359,11 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_
{ {
noaccel = true; noaccel = true;
} }
// If drawing with a BOOM colormap, disable acceleration.
if (mybasecolormap == &NormalLight && NormalLight.Maps != realcolormaps)
{
noaccel = true;
}
// If the main colormap has fixed lights, and this sprite is being drawn with that // If the main colormap has fixed lights, and this sprite is being drawn with that
// colormap, disable acceleration so that the lights can remain fixed. // colormap, disable acceleration so that the lights can remain fixed.
if (!noaccel && realfixedcolormap == NULL && if (!noaccel && realfixedcolormap == NULL &&

View file

@ -2348,7 +2348,6 @@ class AMusicChanger : public ASectorAction
DECLARE_CLASS (AMusicChanger, ASectorAction) DECLARE_CLASS (AMusicChanger, ASectorAction)
public: public:
virtual bool DoTriggerAction (AActor *triggerer, int activationType); virtual bool DoTriggerAction (AActor *triggerer, int activationType);
virtual void Tick();
virtual void PostBeginPlay(); virtual void PostBeginPlay();
}; };
@ -2356,49 +2355,27 @@ IMPLEMENT_CLASS(AMusicChanger)
bool AMusicChanger::DoTriggerAction (AActor *triggerer, int activationType) bool AMusicChanger::DoTriggerAction (AActor *triggerer, int activationType)
{ {
if (activationType & SECSPAC_Enter) if (activationType & SECSPAC_Enter && triggerer->player != NULL)
{ {
if (args[0] == 0 || level.info->MusicMap.CheckKey(args[0])) if (triggerer->player->MUSINFOactor != this)
{ {
level.nextmusic = args[0]; triggerer->player->MUSINFOactor = this;
reactiontime = 30; triggerer->player->MUSINFOtics = 30;
} }
} }
return Super::DoTriggerAction (triggerer, activationType); return Super::DoTriggerAction (triggerer, activationType);
} }
void AMusicChanger::Tick()
{
Super::Tick();
if (reactiontime > -1 && --reactiontime == 0)
{
// Is it our music that's queued for being played?
if (level.nextmusic == args[0])
{
if (args[0] != 0)
{
FName *music = level.info->MusicMap.CheckKey(args[0]);
if (music != NULL)
{
S_ChangeMusic(music->GetChars(), args[1]);
}
}
else
{
S_ChangeMusic("*");
}
}
}
}
void AMusicChanger::PostBeginPlay() void AMusicChanger::PostBeginPlay()
{ {
// The music changer should consider itself activated if the player // The music changer should consider itself activated if the player
// spawns in its sector as well as if it enters the sector during a P_TryMove. // spawns in its sector as well as if it enters the sector during a P_TryMove.
Super::PostBeginPlay(); Super::PostBeginPlay();
if (players[consoleplayer].mo && players[consoleplayer].mo->Sector == this->Sector) for (int i = 0; i < MAXPLAYERS; ++i)
{ {
TriggerAction(players[consoleplayer].mo, SECSPAC_Enter); if (playeringame[i] && players[i].mo && players[i].mo->Sector == this->Sector)
{
TriggerAction(players[i].mo, SECSPAC_Enter);
}
} }
} }

View file

@ -68,7 +68,7 @@ static FRandom pr_animatepictures ("AnimatePics");
// //
//========================================================================== //==========================================================================
void FTextureManager::AddAnim (FAnimDef *anim) FAnimDef *FTextureManager::AddAnim (FAnimDef *anim)
{ {
// Search for existing duplicate. // Search for existing duplicate.
for (unsigned int i = 0; i < mAnimations.Size(); ++i) for (unsigned int i = 0; i < mAnimations.Size(); ++i)
@ -78,11 +78,12 @@ void FTextureManager::AddAnim (FAnimDef *anim)
// Found one! // Found one!
free (mAnimations[i]); free (mAnimations[i]);
mAnimations[i] = anim; mAnimations[i] = anim;
return; return anim;
} }
} }
// Didn't find one, so add it at the end. // Didn't find one, so add it at the end.
mAnimations.Push (anim); mAnimations.Push (anim);
return anim;
} }
//========================================================================== //==========================================================================
@ -94,7 +95,7 @@ void FTextureManager::AddAnim (FAnimDef *anim)
// //
//========================================================================== //==========================================================================
void FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD speedmin, DWORD speedrange) FAnimDef *FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, DWORD speedmin, DWORD speedrange)
{ {
if (AreTexturesCompatible(picnum, picnum + (animcount - 1))) if (AreTexturesCompatible(picnum, picnum + (animcount - 1)))
{ {
@ -102,13 +103,15 @@ void FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, int animt
anim->CurFrame = 0; anim->CurFrame = 0;
anim->BasePic = picnum; anim->BasePic = picnum;
anim->NumFrames = animcount; anim->NumFrames = animcount;
anim->AnimType = animtype; anim->AnimType = FAnimDef::ANIM_Forward;
anim->bDiscrete = false;
anim->SwitchTime = 0; anim->SwitchTime = 0;
anim->Frames[0].SpeedMin = speedmin; anim->Frames[0].SpeedMin = speedmin;
anim->Frames[0].SpeedRange = speedrange; anim->Frames[0].SpeedRange = speedrange;
anim->Frames[0].FramePic = anim->BasePic; anim->Frames[0].FramePic = anim->BasePic;
AddAnim (anim); return AddAnim (anim);
} }
return NULL;
} }
//========================================================================== //==========================================================================
@ -119,16 +122,17 @@ void FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, int animt
// //
//========================================================================== //==========================================================================
void FTextureManager::AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames) FAnimDef *FTextureManager::AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames)
{ {
FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1) * sizeof(frames[0])); FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1) * sizeof(frames[0]));
anim->BasePic = picnum; anim->BasePic = picnum;
anim->NumFrames = frames.Size(); anim->NumFrames = frames.Size();
anim->CurFrame = 0; anim->CurFrame = 0;
anim->AnimType = FAnimDef::ANIM_DiscreteFrames; anim->AnimType = FAnimDef::ANIM_Forward;
anim->bDiscrete = true;
anim->SwitchTime = 0; anim->SwitchTime = 0;
memcpy (&anim->Frames[0], &frames[0], frames.Size() * sizeof(frames[0])); memcpy (&anim->Frames[0], &frames[0], frames.Size() * sizeof(frames[0]));
AddAnim (anim); return AddAnim (anim);
} }
//========================================================================== //==========================================================================
@ -249,7 +253,8 @@ void FTextureManager::InitAnimated (void)
} }
// Speed is stored as tics, but we want ms so scale accordingly. // Speed is stored as tics, but we want ms so scale accordingly.
AddSimpleAnim (pic1, pic2 - pic1 + 1, animtype, Scale (animspeed, 1000, 35)); FAnimDef *adef = AddSimpleAnim (pic1, pic2 - pic1 + 1, Scale (animspeed, 1000, 35));
if (adef != NULL) adef->AnimType = animtype;
} }
} }
} }
@ -333,6 +338,8 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
FTextureID picnum; FTextureID picnum;
int defined = 0; int defined = 0;
bool optional = false, missing = false; bool optional = false, missing = false;
FAnimDef *ani = NULL;
BYTE type = FAnimDef::ANIM_Forward;
sc.MustGetString (); sc.MustGetString ();
if (sc.Compare ("optional")) if (sc.Compare ("optional"))
@ -370,6 +377,22 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
} }
continue; continue;
} }
else if (sc.Compare ("Oscillate"))
{
if (type == FAnimDef::ANIM_Random)
{
sc.ScriptError ("You cannot use \"random\" and \"oscillate\" together in a single animation.");
}
type = FAnimDef::ANIM_OscillateUp;
}
else if (sc.Compare("Random"))
{
if (type == FAnimDef::ANIM_OscillateUp)
{
sc.ScriptError ("You cannot use \"random\" and \"oscillate\" together in a single animation.");
}
type = FAnimDef::ANIM_Random;
}
else if (sc.Compare ("range")) else if (sc.Compare ("range"))
{ {
if (defined == 2) if (defined == 2)
@ -381,7 +404,7 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
sc.ScriptError ("You can only use one \"range\" per animation."); sc.ScriptError ("You can only use one \"range\" per animation.");
} }
defined = 1; defined = 1;
ParseRangeAnim (sc, picnum, usetype, missing); ani = ParseRangeAnim (sc, picnum, usetype, missing);
} }
else if (sc.Compare ("pic")) else if (sc.Compare ("pic"))
{ {
@ -407,7 +430,12 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
{ {
sc.ScriptError ("Animation needs at least 2 frames"); sc.ScriptError ("Animation needs at least 2 frames");
} }
AddComplexAnim (picnum, frames); ani = AddComplexAnim (picnum, frames);
}
if (ani != NULL && type != FAnimDef::ANIM_Forward)
{
if (ani->AnimType == FAnimDef::ANIM_Backward && type == FAnimDef::ANIM_OscillateUp) ani->AnimType = FAnimDef::ANIM_OscillateDown;
else ani->AnimType = type;
} }
} }
@ -420,7 +448,7 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
// //
//========================================================================== //==========================================================================
void FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing) FAnimDef *FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing)
{ {
int type; int type;
FTextureID framenum; FTextureID framenum;
@ -432,7 +460,7 @@ void FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usety
if (framenum == picnum || !picnum.Exists()) if (framenum == picnum || !picnum.Exists())
{ {
return; // Animation is only one frame or does not exist return NULL; // Animation is only one frame or does not exist
} }
if (framenum < picnum) if (framenum < picnum)
{ {
@ -440,18 +468,9 @@ void FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usety
Texture(framenum)->bNoDecals = Texture(picnum)->bNoDecals; Texture(framenum)->bNoDecals = Texture(picnum)->bNoDecals;
swapvalues (framenum, picnum); swapvalues (framenum, picnum);
} }
if (sc.GetString()) FAnimDef *ani = AddSimpleAnim (picnum, framenum - picnum + 1, min, max - min);
{ if (ani != NULL) ani->AnimType = type;
if (sc.Compare ("Oscillate")) return ani;
{
type = type == FAnimDef::ANIM_Forward ? FAnimDef::ANIM_OscillateUp : FAnimDef::ANIM_OscillateDown;
}
else
{
sc.UnGet ();
}
}
AddSimpleAnim (picnum, framenum - picnum + 1, type, min, max - min);
} }
//========================================================================== //==========================================================================
@ -691,7 +710,7 @@ void FTextureManager::FixAnimations ()
for (i = 0; i < mAnimations.Size(); ++i) for (i = 0; i < mAnimations.Size(); ++i)
{ {
FAnimDef *anim = mAnimations[i]; FAnimDef *anim = mAnimations[i];
if (anim->AnimType == FAnimDef::ANIM_DiscreteFrames) if (anim->bDiscrete)
{ {
if (Texture(anim->BasePic)->bNoRemap0) if (Texture(anim->BasePic)->bNoRemap0)
{ {
@ -830,7 +849,7 @@ FDoorAnimation *FTextureManager::FindAnimatedDoor (FTextureID picnum)
void FAnimDef::SetSwitchTime (DWORD mstime) void FAnimDef::SetSwitchTime (DWORD mstime)
{ {
int speedframe = (AnimType == FAnimDef::ANIM_DiscreteFrames) ? CurFrame : 0; int speedframe = bDiscrete ? CurFrame : 0;
SwitchTime = mstime + Frames[speedframe].SpeedMin; SwitchTime = mstime + Frames[speedframe].SpeedMin;
if (Frames[speedframe].SpeedRange != 0) if (Frames[speedframe].SpeedRange != 0)
@ -889,7 +908,6 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
{ {
default: default:
case FAnimDef::ANIM_Forward: case FAnimDef::ANIM_Forward:
case FAnimDef::ANIM_DiscreteFrames:
anim->CurFrame = (anim->CurFrame + 1) % anim->NumFrames; anim->CurFrame = (anim->CurFrame + 1) % anim->NumFrames;
break; break;
@ -904,6 +922,16 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
} }
break; break;
case FAnimDef::ANIM_Random:
// select a random frame other than the current one
if (anim->NumFrames > 1)
{
WORD rndFrame = (WORD)pr_animatepictures(anim->NumFrames - 1);
if (rndFrame >= anim->CurFrame) rndFrame++;
anim->CurFrame = rndFrame;
}
break;
case FAnimDef::ANIM_OscillateUp: case FAnimDef::ANIM_OscillateUp:
anim->CurFrame = anim->CurFrame + 1; anim->CurFrame = anim->CurFrame + 1;
if (anim->CurFrame >= anim->NumFrames - 1) if (anim->CurFrame >= anim->NumFrames - 1)
@ -923,7 +951,7 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
anim->SetSwitchTime (mstime); anim->SetSwitchTime (mstime);
} }
if (anim->AnimType == FAnimDef::ANIM_DiscreteFrames) if (anim->bDiscrete)
{ {
SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic); SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic);
} }

View file

@ -1245,6 +1245,12 @@ void FTextureManager::PrecacheLevel (void)
memset (hitlist, 0, cnt); memset (hitlist, 0, cnt);
screen->GetHitlist(hitlist); screen->GetHitlist(hitlist);
for (unsigned i = 0; i < level.info->PrecacheTextures.Size(); i++)
{
hitlist[level.info->PrecacheTextures[i].GetIndex()] |= 1;
}
for (int i = cnt - 1; i >= 0; i--) for (int i = cnt - 1; i >= 0; i--)
{ {
Renderer->PrecacheTexture(ByIndex(i), hitlist[i]); Renderer->PrecacheTexture(ByIndex(i), hitlist[i]);

View file

@ -87,6 +87,7 @@ struct FAnimDef
WORD NumFrames; WORD NumFrames;
WORD CurFrame; WORD CurFrame;
BYTE AnimType; BYTE AnimType;
bool bDiscrete; // taken out of AnimType to have better control
DWORD SwitchTime; // Time to advance to next frame DWORD SwitchTime; // Time to advance to next frame
struct FAnimFrame struct FAnimFrame
{ {
@ -100,7 +101,7 @@ struct FAnimDef
ANIM_Backward, ANIM_Backward,
ANIM_OscillateUp, ANIM_OscillateUp,
ANIM_OscillateDown, ANIM_OscillateDown,
ANIM_DiscreteFrames ANIM_Random
}; };
void SetSwitchTime (DWORD mstime); void SetSwitchTime (DWORD mstime);
@ -493,14 +494,14 @@ private:
void InitBuildTiles (); void InitBuildTiles ();
// Animation stuff // Animation stuff
void AddAnim (FAnimDef *anim); FAnimDef *AddAnim (FAnimDef *anim);
void FixAnimations (); void FixAnimations ();
void InitAnimated (); void InitAnimated ();
void InitAnimDefs (); void InitAnimDefs ();
void AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD speedmin, DWORD speedrange=0); FAnimDef *AddSimpleAnim (FTextureID picnum, int animcount, DWORD speedmin, DWORD speedrange=0);
void AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames); FAnimDef *AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames);
void ParseAnim (FScanner &sc, int usetype); void ParseAnim (FScanner &sc, int usetype);
void ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing); FAnimDef *ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing);
void ParsePicAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames); void ParsePicAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames);
void ParseWarp(FScanner &sc); void ParseWarp(FScanner &sc);
void ParseCameraTexture(FScanner &sc); void ParseCameraTexture(FScanner &sc);

View file

@ -5186,15 +5186,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed)
ref->Speed = speed; ref->Speed = speed;
} }
static bool DoCheckSpecies(AActor *mo, FName species, bool exclude) static bool DoCheckSpecies(AActor *mo, FName filterSpecies, bool exclude)
{ {
return (!(species) || mo->Species == NAME_None || (species && ((exclude) ? (mo->Species != species) : (mo->Species == species)))); FName actorSpecies = mo->GetSpecies();
if (filterSpecies == NAME_None) return true;
return exclude ? (actorSpecies != filterSpecies) : (actorSpecies == filterSpecies);
} }
static bool DoCheckFilter(AActor *mo, const PClass *filter, bool exclude) static bool DoCheckClass(AActor *mo, const PClass *filterClass, bool exclude)
{ {
const PClass *c1 = mo->GetClass(); const PClass *actorClass = mo->GetClass();
return (!(filter) || (filter == NULL) || (filter && ((exclude) ? (c1 != filter) : (c1 == filter)))); if (filterClass == NULL) return true;
return exclude ? (actorClass != filterClass) : (actorClass == filterClass);
} }
//=========================================================================== //===========================================================================
@ -5228,23 +5231,23 @@ enum DMSS
static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageType, int flags, const PClass *filter, FName species) static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageType, int flags, const PClass *filter, FName species)
{ {
bool filterpass = DoCheckFilter(dmgtarget, filter, (flags & DMSS_EXFILTER) ? true : false), bool filterpass = DoCheckClass(dmgtarget, filter, !!(flags & DMSS_EXFILTER)),
speciespass = DoCheckSpecies(dmgtarget, species, (flags & DMSS_EXSPECIES) ? true : false); speciespass = DoCheckSpecies(dmgtarget, species, !!(flags & DMSS_EXSPECIES));
if ((flags & DMSS_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass)) if ((flags & DMSS_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass))
{ {
int dmgFlags = 0; int dmgFlags = 0;
if (flags & DMSS_FOILINVUL) if (flags & DMSS_FOILINVUL)
dmgFlags += DMG_FOILINVUL; dmgFlags |= DMG_FOILINVUL;
if (flags & DMSS_FOILBUDDHA) if (flags & DMSS_FOILBUDDHA)
dmgFlags += DMG_FOILBUDDHA; dmgFlags |= DMG_FOILBUDDHA;
if ((flags & DMSS_KILL) || (flags & DMSS_NOFACTOR)) //Kill implies NoFactor if (flags & (DMSS_KILL | DMSS_NOFACTOR)) //Kill implies NoFactor
dmgFlags += DMG_NO_FACTOR; dmgFlags |= DMG_NO_FACTOR;
if (!(flags & DMSS_AFFECTARMOR) || (flags & DMSS_KILL)) //Kill overrides AffectArmor if (!(flags & DMSS_AFFECTARMOR) || (flags & DMSS_KILL)) //Kill overrides AffectArmor
dmgFlags += DMG_NO_ARMOR; dmgFlags |= DMG_NO_ARMOR;
if (flags & DMSS_KILL) //Kill adds the value of the damage done to it. Allows for more controlled extreme death types. if (flags & DMSS_KILL) //Kill adds the value of the damage done to it. Allows for more controlled extreme death types.
amount += dmgtarget->health; amount += dmgtarget->health;
if (flags & DMSS_NOPROTECT) //Ignore PowerProtection. if (flags & DMSS_NOPROTECT) //Ignore PowerProtection.
dmgFlags += DMG_NO_PROTECT; dmgFlags |= DMG_NO_PROTECT;
if (amount > 0) if (amount > 0)
P_DamageMobj(dmgtarget, self, self, amount, DamageType, dmgFlags); //Should wind up passing them through just fine. P_DamageMobj(dmgtarget, self, self, amount, DamageType, dmgFlags); //Should wind up passing them through just fine.
@ -5408,16 +5411,16 @@ enum KILS
static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags, const PClass *filter, FName species) static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags, const PClass *filter, FName species)
{ {
bool filterpass = DoCheckFilter(killtarget, filter, (flags & KILS_EXFILTER) ? true : false), bool filterpass = DoCheckClass(killtarget, filter, !!(flags & KILS_EXFILTER)),
speciespass = DoCheckSpecies(killtarget, species, (flags & KILS_EXSPECIES) ? true : false); speciespass = DoCheckSpecies(killtarget, species, !!(flags & KILS_EXSPECIES));
if ((flags & KILS_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass)) //Check this first. I think it'll save the engine a lot more time this way. if ((flags & KILS_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass)) //Check this first. I think it'll save the engine a lot more time this way.
{ {
int dmgFlags = DMG_NO_ARMOR + DMG_NO_FACTOR; int dmgFlags = DMG_NO_ARMOR | DMG_NO_FACTOR;
if (KILS_FOILINVUL) if (KILS_FOILINVUL)
dmgFlags += DMG_FOILINVUL; dmgFlags |= DMG_FOILINVUL;
if (KILS_FOILBUDDHA) if (KILS_FOILBUDDHA)
dmgFlags += DMG_FOILBUDDHA; dmgFlags |= DMG_FOILBUDDHA;
if ((killtarget->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) if ((killtarget->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES))
@ -5426,7 +5429,8 @@ static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags
//Check to see if it's invulnerable. Disregarded if foilinvul is on, but never works on a missile with NODAMAGE //Check to see if it's invulnerable. Disregarded if foilinvul is on, but never works on a missile with NODAMAGE
//since that's the whole point of it. //since that's the whole point of it.
if ((!(killtarget->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && if ((!(killtarget->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) &&
(!(killtarget->flags2 & MF7_BUDDHA) || (flags & KILS_FOILBUDDHA)) && !(killtarget->flags5 & MF5_NODAMAGE)) (!(killtarget->flags7 & MF7_BUDDHA) || (flags & KILS_FOILBUDDHA)) &&
!(killtarget->flags5 & MF5_NODAMAGE))
{ {
P_ExplodeMissile(killtarget, NULL, NULL); P_ExplodeMissile(killtarget, NULL, NULL);
} }
@ -5568,8 +5572,8 @@ enum RMVF_flags
static void DoRemove(AActor *removetarget, int flags, const PClass *filter, FName species) static void DoRemove(AActor *removetarget, int flags, const PClass *filter, FName species)
{ {
bool filterpass = DoCheckFilter(removetarget, filter, (flags & RMVF_EXFILTER) ? true : false), bool filterpass = DoCheckClass(removetarget, filter, !!(flags & RMVF_EXFILTER)),
speciespass = DoCheckSpecies(removetarget, species, (flags & RMVF_EXSPECIES) ? true : false); speciespass = DoCheckSpecies(removetarget, species, !!(flags & RMVF_EXSPECIES));
if ((flags & RMVF_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass)) if ((flags & RMVF_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass))
{ {
if ((flags & RMVF_EVERYTHING)) if ((flags & RMVF_EVERYTHING))
@ -5722,33 +5726,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Remove)
// A_SetTeleFog // A_SetTeleFog
// //
// Sets the teleport fog(s) for the calling actor. // Sets the teleport fog(s) for the calling actor.
// Takes a name of the classes for te source and destination. // Takes a name of the classes for the source and destination.
// Can set both at the same time. Use "" to retain the previous fog without
// changing it.
//=========================================================================== //===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTeleFog) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTeleFog)
{ {
ACTION_PARAM_START(2); ACTION_PARAM_START(2);
ACTION_PARAM_NAME(oldpos, 0); ACTION_PARAM_CLASS(oldpos, 0);
ACTION_PARAM_NAME(newpos, 1); ACTION_PARAM_CLASS(newpos, 1);
const PClass *check = PClass::FindClass(oldpos);
if (check == NULL || !stricmp(oldpos, "none") || !stricmp(oldpos, "null"))
self->TeleFogSourceType = NULL;
else if (!stricmp(oldpos, ""))
{ //Don't change it if it's just ""
}
else
self->TeleFogSourceType = check;
check = PClass::FindClass(newpos); self->TeleFogSourceType = oldpos;
if (check == NULL || !stricmp(newpos, "none") || !stricmp(newpos, "null")) self->TeleFogDestType = newpos;
self->TeleFogDestType = NULL;
else if (!stricmp(newpos, ""))
{ //Don't change it if it's just ""
}
else
self->TeleFogDestType = check;
} }
//=========================================================================== //===========================================================================

View file

@ -1422,7 +1422,7 @@ DEFINE_PROPERTY(stamina, I, Actor)
DEFINE_PROPERTY(telefogsourcetype, S, Actor) DEFINE_PROPERTY(telefogsourcetype, S, Actor)
{ {
PROP_STRING_PARM(str, 0); PROP_STRING_PARM(str, 0);
if (!stricmp(str, "") || (!stricmp(str, "none")) || (!stricmp(str, "null")) || *str == 0) defaults->TeleFogSourceType = NULL; if (!stricmp(str, "") || !stricmp(str, "none")) defaults->TeleFogSourceType = NULL;
else defaults->TeleFogSourceType = FindClassTentative(str,"TeleportFog"); else defaults->TeleFogSourceType = FindClassTentative(str,"TeleportFog");
} }
@ -1432,7 +1432,7 @@ DEFINE_PROPERTY(telefogsourcetype, S, Actor)
DEFINE_PROPERTY(telefogdesttype, S, Actor) DEFINE_PROPERTY(telefogdesttype, S, Actor)
{ {
PROP_STRING_PARM(str, 0); PROP_STRING_PARM(str, 0);
if (!stricmp(str, "") || (!stricmp(str, "none")) || (!stricmp(str, "null")) || *str == 0) defaults->TeleFogDestType = NULL; if (!stricmp(str, "") || !stricmp(str, "none")) defaults->TeleFogDestType = NULL;
else defaults->TeleFogDestType = FindClassTentative(str, "TeleportFog"); else defaults->TeleFogDestType = FindClassTentative(str, "TeleportFog");
} }

View file

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

View file

@ -56,6 +56,7 @@
#include "doomerrors.h" #include "doomerrors.h"
#include "resourcefiles/resourcefile.h" #include "resourcefiles/resourcefile.h"
#include "md5.h" #include "md5.h"
#include "doomstat.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -300,6 +301,56 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadinfo)
AddFile(path, embedded); AddFile(path, embedded);
} }
} }
if (hashfile)
{
BYTE cksum[16];
char cksumout[33];
memset(cksumout, 0, sizeof(cksumout));
FileReader *reader = wadinfo;
if (reader != NULL)
{
MD5Context md5;
reader->Seek(0, SEEK_SET);
md5.Update(reader, reader->GetLength());
md5.Final(cksum);
for (size_t j = 0; j < sizeof(cksum); ++j)
{
sprintf(cksumout + (j * 2), "%02X", cksum[j]);
}
fprintf(hashfile, "file: %s, hash: %s, size: %d\n", filename, cksumout, reader->GetLength());
}
else
fprintf(hashfile, "file: %s, Directory structure\n", filename);
for (DWORD i = 0; i < resfile->LumpCount(); i++)
{
FResourceLump *lump = resfile->GetLump(i);
if (!(lump->Flags & LUMPF_EMBEDDED))
{
reader = lump->NewReader();
MD5Context md5;
md5.Update(reader, lump->LumpSize);
md5.Final(cksum);
for (size_t j = 0; j < sizeof(cksum); ++j)
{
sprintf(cksumout + (j * 2), "%02X", cksum[j]);
}
fprintf(hashfile, "file: %s, lump: %s, hash: %s, size: %d\n", filename, lump->FullName ? lump->FullName : lump->Name, cksumout, lump->LumpSize);
delete reader;
}
}
}
return; return;
} }
} }

View file

@ -561,37 +561,26 @@ void I_DetectOS(void)
{ {
if (info.dwMinorVersion == 0) if (info.dwMinorVersion == 0)
{ {
if (info.wProductType == VER_NT_WORKSTATION) osname = (info.wProductType == VER_NT_WORKSTATION) ? "Vista" : "Server 2008";
{
osname = "Vista";
}
else
{
osname = "Server 2008";
}
} }
else if (info.dwMinorVersion == 1) else if (info.dwMinorVersion == 1)
{ {
if (info.wProductType == VER_NT_WORKSTATION) osname = (info.wProductType == VER_NT_WORKSTATION) ? "7" : "Server 2008 R2";
{
osname = "7";
}
else
{
osname = "Server 2008 R2";
}
} }
else if (info.dwMinorVersion == 2) else if (info.dwMinorVersion == 2)
{ {
// Microsoft broke this API for 8.1 so without jumping through hoops it won't be possible anymore to detect never versions aside from the build number, especially for older compilers. // Starting with Windows 8.1, you need to specify in your manifest
if (info.wProductType == VER_NT_WORKSTATION) // the highest version of Windows you support, which will also be the
{ // highest version of Windows this function returns.
osname = "8 (or higher)"; osname = (info.wProductType == VER_NT_WORKSTATION) ? "8" : "Server 2012";
} }
else else if (info.dwMinorVersion == 3)
{ {
osname = "Server 2012 (or higher)"; osname = (info.wProductType == VER_NT_WORKSTATION) ? "8.1" : "Server 2012 R2";
} }
else if (info.dwMinorVersion == 4)
{
osname = (info.wProductType == VER_NT_WORKSTATION) ? "10 (or higher)" : "Server 10 (or higher)";
} }
} }
break; break;

View file

@ -5,4 +5,23 @@
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
</dependentAssembly> </dependentAssembly>
</dependency> </dependency>
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly> </assembly>

View file

@ -25,8 +25,7 @@ if( NOT CMAKE_CROSSCOMPILING )
endif( NOT CMAKE_CROSSCOMPILING ) endif( NOT CMAKE_CROSSCOMPILING )
if( MT_MERGE ) if( MT_MERGE )
get_target_property( UPDATEREVISION_EXE updaterevision LOCATION )
add_custom_command(TARGET updaterevision POST_BUILD add_custom_command(TARGET updaterevision POST_BUILD
COMMAND mt -inputresource:${UPDATEREVISION_EXE} -manifest ${CMAKE_CURRENT_SOURCE_DIR}/trustinfo.txt -outputresource:${UPDATEREVISION_EXE} -nologo COMMAND mt -inputresource:$<TARGET_FILE:updaterevision> -manifest ${CMAKE_CURRENT_SOURCE_DIR}/trustinfo.txt -outputresource:$<TARGET_FILE:updaterevision> -nologo
COMMENT "Embedding trustinfo into updaterevision" ) COMMENT "Embedding trustinfo into updaterevision" )
endif( MT_MERGE ) endif( MT_MERGE )

View file

@ -325,7 +325,7 @@ ACTOR Actor native //: Thinker
action native A_GiveToSiblings(class<Inventory> itemtype, int amount = 0); action native A_GiveToSiblings(class<Inventory> itemtype, int amount = 0);
action native A_TakeFromChildren(class<Inventory> itemtype, int amount = 0); action native A_TakeFromChildren(class<Inventory> itemtype, int amount = 0);
action native A_TakeFromSiblings(class<Inventory> itemtype, int amount = 0); action native A_TakeFromSiblings(class<Inventory> itemtype, int amount = 0);
action native A_SetTeleFog(name oldpos, name newpos); action native A_SetTeleFog(class<TeleportFog> oldpos, class<TeleportFog> newpos);
action native A_SwapTeleFog(); action native A_SwapTeleFog();
action native A_SetFloatBobPhase(int bob); action native A_SetFloatBobPhase(int bob);
action native A_SetHealth(int health, int ptr = AAPTR_DEFAULT); action native A_SetHealth(int health, int ptr = AAPTR_DEFAULT);

View file

@ -124,6 +124,14 @@ BA530202AF0BA0C6CBAE6A0C7076FB72 // Requiem map04
3CA5493FEFF2E27BFD4181E6C4A3C2BF // The Waterfront map01 3CA5493FEFF2E27BFD4181E6C4A3C2BF // The Waterfront map01
CBDFEFAC579A62DE8F1B48CA4A09D381 // gather2.wad map05 and darkside.wad map01 CBDFEFAC579A62DE8F1B48CA4A09D381 // gather2.wad map05 and darkside.wad map01
C7A2FAFB0AFB2632C50AD625CDB50E51 // Reverie map18 C7A2FAFB0AFB2632C50AD625CDB50E51 // Reverie map18
9E5724BC6135AA6F86EE54FD4D91F1E2 // Project X map14
6DA6FCBA8089161BDEC6A1D3F6C8D60F // Eternal Doom map25
01899825FFEAE016D39C02A7DA4B218F // Archie map01
1D9F3AFDC2517C2E450491ED13896712 // Seej map01
0AE745A3AB86D15FB2FB74489962C421 // 6pack2 map02
2EA635C6B6AEC76B6BC77448DAB22F9A // Squadron 417 map21
1E998262EE319B7D088E01DE782E6B41 // Mayhem 2013 map05
A81E2734F735A82720D8E0F1442BA0C9 // Imp's [sic] are Ghost Gods map01
{ {
corpsegibs corpsegibs
vileghosts vileghosts

View file

@ -117,6 +117,7 @@
/> />
<Tool <Tool
Name="VCManifestTool" Name="VCManifestTool"
AdditionalManifestFiles="src\win32\zdoom.exe.manifest"
SuppressStartupBanner="true" SuppressStartupBanner="true"
AssemblyIdentity="" AssemblyIdentity=""
/> />
@ -233,6 +234,7 @@
/> />
<Tool <Tool
Name="VCManifestTool" Name="VCManifestTool"
AdditionalManifestFiles="src\win32\zdoom.exe.manifest"
/> />
<Tool <Tool
Name="VCXDCMakeTool" Name="VCXDCMakeTool"
@ -339,6 +341,7 @@
/> />
<Tool <Tool
Name="VCManifestTool" Name="VCManifestTool"
AdditionalManifestFiles="src\win32\zdoom.exe.manifest"
/> />
<Tool <Tool
Name="VCXDCMakeTool" Name="VCXDCMakeTool"
@ -446,6 +449,7 @@
/> />
<Tool <Tool
Name="VCManifestTool" Name="VCManifestTool"
AdditionalManifestFiles="src\win32\zdoom.exe.manifest"
/> />
<Tool <Tool
Name="VCXDCMakeTool" Name="VCXDCMakeTool"
@ -2616,6 +2620,14 @@
RelativePath=".\src\oplsynth\muslib.h" RelativePath=".\src\oplsynth\muslib.h"
> >
</File> </File>
<File
RelativePath=".\src\oplsynth\nukedopl3.cpp"
>
</File>
<File
RelativePath=".\src\oplsynth\nukedopl3.h"
>
</File>
<File <File
RelativePath=".\src\oplsynth\opl.h" RelativePath=".\src\oplsynth\opl.h"
> >
@ -2632,14 +2644,6 @@
RelativePath=".\src\oplsynth\opl_mus_player.h" RelativePath=".\src\oplsynth\opl_mus_player.h"
> >
</File> </File>
<File
RelativePath=".\src\oplsynth\nukedopl3.cpp"
>
</File>
<File
RelativePath=".\src\oplsynth\nukedopl3.h"
>
</File>
<Filter <Filter
Name="DOSBox" Name="DOSBox"
> >