mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
6eb4e2a224
38 changed files with 585 additions and 400 deletions
|
@ -1,6 +1,15 @@
|
|||
cmake_minimum_required( VERSION 2.4 )
|
||||
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} )
|
||||
include( CreateLaunchers )
|
||||
include( FindPackageHandleStandardArgs )
|
||||
|
@ -26,8 +35,6 @@ endif(CMAKE_CROSSCOMPILING)
|
|||
|
||||
# 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" )
|
||||
|
@ -36,20 +43,22 @@ function( add_pk3 PK3_NAME PK3_DIR )
|
|||
|
||||
if( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE )
|
||||
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}
|
||||
DEPENDS zipdir )
|
||||
else( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE )
|
||||
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 )
|
||||
endif( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE )
|
||||
|
||||
# Touch the zipdir executable here so that the pk3s are forced to rebuild
|
||||
# each time since their dependecy has "changed."
|
||||
add_custom_target( ${PK3_TARGET} ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${ZIPDIR_EXE}
|
||||
DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} )
|
||||
if( NOT NO_GENERATOR_EXPRESSIONS )
|
||||
# Touch the zipdir executable here so that the pk3s are forced to
|
||||
# rebuild each time since their dependecy has "changed."
|
||||
add_custom_target( ${PK3_TARGET} ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E touch $<TARGET_FILE:zipdir>
|
||||
DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} )
|
||||
endif( NOT NO_GENERATOR_EXPRESSIONS )
|
||||
endfunction( add_pk3 )
|
||||
|
||||
# Macro for building libraries without debugging information
|
||||
|
|
|
@ -44,6 +44,10 @@ if(__create_launchers)
|
|||
endif()
|
||||
set(__create_launchers YES)
|
||||
|
||||
if( POLICY CMP0026 )
|
||||
cmake_policy( SET CMP0026 OLD )
|
||||
endif( POLICY CMP0026 )
|
||||
|
||||
include(CleanDirectoryList)
|
||||
|
||||
# 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)
|
||||
foreach(_arg "${RUNTIME_LIBRARIES_ENVIRONMENT}" ${ENVIRONMENT})
|
||||
string(CONFIGURE
|
||||
"@USERFILE_ENVIRONMENT@@LAUNCHER_LINESEP@@_arg@"
|
||||
"${USERFILE_ENVIRONMENT}${LAUNCHER_LINESEP}${_arg}"
|
||||
USERFILE_ENVIRONMENT
|
||||
@ONLY)
|
||||
string(CONFIGURE
|
||||
|
|
|
@ -19,18 +19,16 @@ if( NOT MSVC AND NOT APPLE )
|
|||
if( NOT CMAKE_CROSSCOMPILING )
|
||||
add_executable( arithchk arithchk.c )
|
||||
endif( NOT CMAKE_CROSSCOMPILING )
|
||||
get_target_property( ARITHCHK_EXE arithchk LOCATION )
|
||||
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 )
|
||||
|
||||
if( NOT CMAKE_CROSSCOMPILING )
|
||||
add_executable( qnan qnan.c arith.h )
|
||||
set( CROSS_EXPORTS ${CROSS_EXPORTS} arithchk qnan PARENT_SCOPE )
|
||||
endif( NOT CMAKE_CROSSCOMPILING )
|
||||
get_target_property( QNAN_EXE qnan LOCATION )
|
||||
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 )
|
||||
|
||||
set( GEN_FP_FILES arith.h gd_qnan.h )
|
||||
|
@ -44,7 +42,4 @@ add_library( gdtoa
|
|||
misc.c
|
||||
)
|
||||
target_link_libraries( gdtoa )
|
||||
if( GEN_FP_DEPS )
|
||||
add_dependencies( gdtoa ${GEN_FP_DEPS} )
|
||||
endif( GEN_FP_DEPS )
|
||||
|
||||
|
|
|
@ -522,10 +522,8 @@ endif( BACKPATCH )
|
|||
|
||||
# Update gitinfo.h
|
||||
|
||||
get_target_property( UPDATEREVISION_EXE updaterevision LOCATION )
|
||||
|
||||
add_custom_target( revision_check ALL
|
||||
COMMAND ${UPDATEREVISION_EXE} src/gitinfo.h
|
||||
COMMAND updaterevision src/gitinfo.h
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
DEPENDS updaterevision )
|
||||
|
||||
|
@ -651,17 +649,14 @@ else( NO_ASM )
|
|||
endif( X64 )
|
||||
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
|
||||
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}
|
||||
DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y )
|
||||
|
||||
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 )
|
||||
|
||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
|
||||
|
|
|
@ -130,7 +130,7 @@ static const FBinding DefBindings[] =
|
|||
static const FBinding DefRavenBindings[] =
|
||||
{
|
||||
{ "pgup", "+moveup" },
|
||||
{ "insert", "+movedown" },
|
||||
{ "ins", "+movedown" },
|
||||
{ "home", "land" },
|
||||
{ "pgdn", "+lookup" },
|
||||
{ "del", "+lookdown" },
|
||||
|
|
|
@ -889,21 +889,42 @@ CCMD(info)
|
|||
"the NOBLOCKMAP flag or have height/radius of 0.\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CCMD(monster)
|
||||
{
|
||||
AActor * mo;
|
||||
typedef bool (*ActorTypeChecker) (AActor *);
|
||||
|
||||
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;
|
||||
|
||||
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",
|
||||
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)
|
||||
{
|
||||
AActor * mo;
|
||||
|
||||
if (CheckCheatmode ()) return;
|
||||
TThinkerIterator<AActor> it;
|
||||
|
||||
while ( (mo = it.Next()) )
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
PrintFilteredActorList(IsActorAnItem, argv.argc() > 1 ? argv[1] : NULL);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CCMD(countitems)
|
||||
{
|
||||
if (CheckCheatmode ()) return;
|
||||
|
||||
PrintFilteredActorList(IsActorACountItem, argv.argc() > 1 ? argv[1] : NULL);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -595,12 +595,13 @@ CCMD (mapchecksum)
|
|||
else
|
||||
{
|
||||
map->GetChecksum(cksum);
|
||||
const char *wadname = Wads.GetWadName(Wads.GetLumpFile(map->lumpnum));
|
||||
delete map;
|
||||
for (size_t j = 0; j < sizeof(cksum); ++j)
|
||||
{
|
||||
Printf("%02X", cksum[j]);
|
||||
}
|
||||
Printf(" // %s\n", argv[i]);
|
||||
Printf(" // %s %s\n", wadname, argv[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,6 +214,7 @@ bool autostart;
|
|||
FString StoredWarp;
|
||||
bool advancedemo;
|
||||
FILE *debugfile;
|
||||
FILE *hashfile;
|
||||
event_t events[MAXEVENTS];
|
||||
int eventhead;
|
||||
int eventtail;
|
||||
|
@ -2220,6 +2221,26 @@ void D_DoomMain (void)
|
|||
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();
|
||||
PClass::StaticInit ();
|
||||
atterm(FinalGC);
|
||||
|
@ -2289,6 +2310,11 @@ void D_DoomMain (void)
|
|||
pwads.Clear();
|
||||
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");
|
||||
Wads.InitMultipleFiles (allwads);
|
||||
allwads.Clear();
|
||||
|
|
|
@ -443,10 +443,15 @@ public:
|
|||
|
||||
FName LastDamageType; // [RH] For damage-specific pain and death sounds
|
||||
|
||||
//Added by MC:
|
||||
TObjPtr<DBot> Bot;
|
||||
TObjPtr<AActor> MUSINFOactor; // For MUSINFO purposes
|
||||
SBYTE MUSINFOtics;
|
||||
|
||||
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 BlendG;
|
||||
|
@ -458,8 +463,6 @@ public:
|
|||
int MinPitch; // Viewpitch limits (negative is up, positive is down)
|
||||
int MaxPitch;
|
||||
|
||||
SBYTE crouching;
|
||||
SBYTE crouchdir;
|
||||
fixed_t crouchfactor;
|
||||
fixed_t crouchoffset;
|
||||
fixed_t crouchviewdelta;
|
||||
|
|
|
@ -172,6 +172,7 @@ extern bool playeringame[/*MAXPLAYERS*/];
|
|||
|
||||
// File handling stuff.
|
||||
extern FILE* debugfile;
|
||||
extern FILE* hashfile;
|
||||
|
||||
// if true, load all graphics at level load
|
||||
extern bool precache;
|
||||
|
|
|
@ -1420,7 +1420,7 @@ void FParser::SF_PointToDist(void)
|
|||
double y = floatvalue(t_argv[3]) - floatvalue(t_argv[1]);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -584,7 +584,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
|||
int j;
|
||||
int damage;
|
||||
angle_t an;
|
||||
AActor *thingToHit;
|
||||
AActor *linetarget;
|
||||
|
||||
ACTION_PARAM_START(7);
|
||||
|
@ -615,42 +614,42 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
|||
// self->target is the originator (player) of the missile
|
||||
P_AimLineAttack(self->target, an, distance, &linetarget, vrange);
|
||||
|
||||
if (!linetarget)
|
||||
continue;
|
||||
|
||||
AActor *spray = Spawn(spraytype, linetarget->x, linetarget->y,
|
||||
linetarget->z + (linetarget->height >> 2), ALLOW_REPLACE);
|
||||
|
||||
if (spray)
|
||||
if (linetarget != NULL)
|
||||
{
|
||||
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.
|
||||
continue;
|
||||
if (spray->flags6 & MF6_MTHRUSPECIES && spray->GetSpecies() == linetarget->GetSpecies())
|
||||
{
|
||||
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)
|
||||
{
|
||||
damage = 0;
|
||||
for (j = 0; j < damagecnt; ++j)
|
||||
damage += (pr_bfgspray() & 7) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if this is used, damagecnt will be ignored
|
||||
damage = defdamage;
|
||||
}
|
||||
if (defdamage == 0)
|
||||
{
|
||||
damage = 0;
|
||||
for (j = 0; j < damagecnt; ++j)
|
||||
damage += (pr_bfgspray() & 7) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if this is used, damagecnt will be ignored
|
||||
damage = defdamage;
|
||||
}
|
||||
|
||||
int dmgFlagPass = 0;
|
||||
dmgFlagPass += (spray != NULL && (spray->flags3 & MF3_FOILINVUL)) ? DMG_FOILINVUL : 0; //[MC]Because the original foilinvul wasn't working.
|
||||
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);
|
||||
int newdam = P_DamageMobj(linetarget, self->target, self->target, damage, dmgType, dmgFlags);
|
||||
P_TraceBleed(newdam > 0 ? newdam : damage, linetarget, self->target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -1459,7 +1459,9 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
|||
|
||||
if (SaveVersion >= 3313)
|
||||
{
|
||||
arc << level.nextmusic;
|
||||
// This is a player property now
|
||||
int nextmusic;
|
||||
arc << nextmusic;
|
||||
}
|
||||
|
||||
// Hub transitions must keep the current total time
|
||||
|
|
|
@ -336,6 +336,7 @@ struct level_info_t
|
|||
TArray<FSpecialAction> specialactions;
|
||||
|
||||
TArray<FSoundID> PrecacheSounds;
|
||||
TArray<FTextureID> PrecacheTextures;
|
||||
|
||||
level_info_t()
|
||||
{
|
||||
|
@ -412,7 +413,6 @@ struct FLevelLocals
|
|||
int musicorder;
|
||||
int cdtrack;
|
||||
unsigned int cdid;
|
||||
int nextmusic; // For MUSINFO purposes
|
||||
FTextureID skytexture1;
|
||||
FTextureID skytexture2;
|
||||
|
||||
|
|
|
@ -1065,6 +1065,25 @@ DEFINE_MAP_OPTION(PrecacheSounds, true)
|
|||
} 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)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
|
|
|
@ -138,7 +138,13 @@ FGameConfigFile::FGameConfigFile ()
|
|||
SetValueForKey ("Path", "$PROGDIR", true);
|
||||
#else
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
const PClass *check;
|
||||
// Set the actor's telefog to the specified actor. Handle "" as "don't
|
||||
// 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 (activator != NULL)
|
||||
{
|
||||
check = PClass::FindClass(telefogsrc);
|
||||
if (check == NULL || !stricmp(telefogsrc, "none") || !stricmp(telefogsrc, "null"))
|
||||
activator->TeleFogSourceType = NULL;
|
||||
else
|
||||
activator->TeleFogSourceType = check;
|
||||
|
||||
check = PClass::FindClass(telefogdest);
|
||||
if (check == NULL || !stricmp(telefogdest, "none") || !stricmp(telefogdest, "null"))
|
||||
activator->TeleFogDestType = NULL;
|
||||
else
|
||||
activator->TeleFogDestType = check;
|
||||
if (telefogsrc.IsNotEmpty())
|
||||
activator->TeleFogSourceType = PClass::FindClass(telefogsrc);
|
||||
if (telefogdest.IsNotEmpty())
|
||||
activator->TeleFogDestType = PClass::FindClass(telefogdest);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4793,19 +4787,14 @@ static void SetActorTeleFog(AActor *activator, int tid, FName telefogsrc, FName
|
|||
FActorIterator iterator(tid);
|
||||
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()))
|
||||
{
|
||||
check = PClass::FindClass(telefogsrc);
|
||||
if (check == NULL || !stricmp(telefogsrc, "none") || !stricmp(telefogsrc, "null"))
|
||||
actor->TeleFogSourceType = NULL;
|
||||
else
|
||||
actor->TeleFogSourceType = check;
|
||||
|
||||
check = PClass::FindClass(telefogdest);
|
||||
if (check == NULL || !stricmp(telefogdest, "none") || !stricmp(telefogdest, "null"))
|
||||
actor->TeleFogDestType = NULL;
|
||||
else
|
||||
actor->TeleFogDestType = check;
|
||||
if (telefogsrc.IsNotEmpty())
|
||||
actor->TeleFogSourceType = src;
|
||||
if (telefogdest.IsNotEmpty())
|
||||
actor->TeleFogDestType = dest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5700,10 +5689,10 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
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]),
|
||||
argCount > 8 && args[8] ? args[8] : 0,
|
||||
argCount > 9 && args[9] ? args[9] : 1,
|
||||
argCount > 10 && args[10] ? args[10] : 1,
|
||||
argCount > 11 && args[11] ? args[11] : 1 );
|
||||
argCount > 8 ? args[8] : 0,
|
||||
argCount > 9 ? FIXED2DBL(args[9]) : 1.0,
|
||||
argCount > 10 ? FIXED2DBL(args[10]) : 1.0,
|
||||
argCount > 11 ? FIXED2DBL(args[11]) : 1.0 );
|
||||
}
|
||||
|
||||
case ACSF_SetLineActivation:
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "thingdef/thingdef.h"
|
||||
#include "d_dehacked.h"
|
||||
#include "g_level.h"
|
||||
#include "r_data/r_translate.h"
|
||||
#include "teaminfo.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);
|
||||
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
|
||||
}
|
||||
|
@ -3203,10 +3204,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Die)
|
|||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_NAME(damagetype, 0);
|
||||
|
||||
if (self->flags & MF_MISSILE)
|
||||
P_ExplodeMissile(self, NULL, NULL);
|
||||
else
|
||||
P_DamageMobj (self, NULL, NULL, self->health, damagetype, DMG_FORCED);
|
||||
P_DamageMobj (self, NULL, NULL, self->health, damagetype, DMG_FORCED);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -925,9 +925,9 @@ static inline bool MustForcePain(AActor *target, AActor *inflictor)
|
|||
(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.
|
||||
fakedPain = (isFakePain(target, inflictor));
|
||||
fakedPain = (isFakePain(target, inflictor, damage));
|
||||
forcedPain = (MustForcePain(target, inflictor));
|
||||
|
||||
// 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)
|
||||
{
|
||||
invulpain = true; //This returns -1 later.
|
||||
fakeDamage = damage;
|
||||
goto fakepain; //The label is above the massive pile of checks.
|
||||
// big mess here: What do we use for the pain threshold?
|
||||
// We cannot run the various damage filters below so for consistency it needs to be 0.
|
||||
damage = 0;
|
||||
invulpain = true;
|
||||
goto fakepain;
|
||||
}
|
||||
else
|
||||
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)
|
||||
{
|
||||
|
@ -1035,113 +1031,101 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
{
|
||||
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)
|
||||
{
|
||||
// Invulnerable, and won't wake up
|
||||
return -1;
|
||||
}
|
||||
|
||||
player = target->player;
|
||||
if (player && damage > 1 && damage < TELEFRAG_DAMAGE)
|
||||
if (damage < TELEFRAG_DAMAGE) // TELEFRAG_DAMAGE may not be reduced at all or it may not guarantee its effect.
|
||||
{
|
||||
// Take half damage in trainer mode
|
||||
damage = FixedMul(damage, G_SkillProperty(SKILLP_DamageFactor));
|
||||
}
|
||||
// Special damage types
|
||||
if (inflictor)
|
||||
{
|
||||
if (inflictor->flags4 & MF4_SPECTRAL)
|
||||
player = target->player;
|
||||
if (player && damage > 1)
|
||||
{
|
||||
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)
|
||||
return -1;
|
||||
if (player != NULL)
|
||||
{
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
// 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))
|
||||
{
|
||||
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)
|
||||
goto fakepain;
|
||||
|
||||
// any negative value means that something in the above chain has cancelled out all damage and all damage effects, including pain.
|
||||
return -1;
|
||||
}
|
||||
// Push the target unless the source's weapon's kickback is 0.
|
||||
// (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)
|
||||
&& !(inflictor->flags2 & MF2_NODMGTHRUST)
|
||||
&& !(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);
|
||||
}
|
||||
|
||||
thrust = FLOAT2FIXED(fltthrust);
|
||||
// Don't apply ultra-small damage thrust.
|
||||
if (thrust < FRACUNIT / 100)
|
||||
thrust = 0;
|
||||
|
||||
// Don't apply ultra-small damage thrust
|
||||
if (thrust < FRACUNIT/100) thrust = 0;
|
||||
|
||||
// make fall forwards sometimes
|
||||
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
|
||||
&& thrust < 10*FRACUNIT
|
||||
&& !(target->flags & MF_NOGRAVITY)
|
||||
&& (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL)))
|
||||
&& (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL))
|
||||
)
|
||||
{
|
||||
ang += ANG180;
|
||||
thrust *= 4;
|
||||
|
@ -1230,8 +1216,22 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
if (damage < TELEFRAG_DAMAGE)
|
||||
{ // Still allow telefragging :-(
|
||||
damage = (int)((float)damage * level.teamdamage);
|
||||
if (damage <= 0)
|
||||
if (damage < 0)
|
||||
{
|
||||
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))))
|
||||
{
|
||||
invulpain = true;
|
||||
fakeDamage = damage;
|
||||
goto fakepain;
|
||||
}
|
||||
else
|
||||
|
@ -1390,7 +1389,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
if (target->health <= 0)
|
||||
{
|
||||
//[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.
|
||||
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.
|
||||
|
||||
//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)) &&
|
||||
(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)))
|
||||
{
|
||||
dopain:
|
||||
|
@ -1555,10 +1545,6 @@ dopain:
|
|||
{
|
||||
return -1; //NOW we return -1!
|
||||
}
|
||||
else if (fakedPain)
|
||||
{
|
||||
return holdDamage; //This is the calculated damage after all is said and done.
|
||||
}
|
||||
return damage;
|
||||
}
|
||||
|
||||
|
|
|
@ -1288,7 +1288,7 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
|
|||
|
||||
// Do damage
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
dmgFlagPass += (puffDefaults->flags3 & MF3_FOILINVUL) ? DMG_FOILINVUL : 0; //[MC]Because the original foilinvul check wasn't working.
|
||||
dmgFlagPass += (puffDefaults->flags7 & MF7_FOILBUDDHA) ? DMG_FOILBUDDHA : 0;
|
||||
if (puffDefaults != NULL) // is this even possible?
|
||||
{
|
||||
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);
|
||||
|
||||
if (bleed)
|
||||
|
|
|
@ -4480,7 +4480,8 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
|
|||
p->mo->ResetAirSupply(false);
|
||||
p->Uncrouch();
|
||||
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.
|
||||
|
||||
|
@ -6442,7 +6443,8 @@ void PrintMiscActorInfo(AActor *query)
|
|||
}
|
||||
}
|
||||
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);
|
||||
for (flagi = 0; flagi <= 31; flagi++)
|
||||
|
|
|
@ -309,7 +309,9 @@ player_t::player_t()
|
|||
ConversationNPC(0),
|
||||
ConversationPC(0),
|
||||
ConversationNPCAngle(0),
|
||||
ConversationFaceTalker(0)
|
||||
ConversationFaceTalker(0),
|
||||
MUSINFOactor(0),
|
||||
MUSINFOtics(-1)
|
||||
{
|
||||
memset (&cmd, 0, sizeof(cmd));
|
||||
memset (frags, 0, sizeof(frags));
|
||||
|
@ -400,6 +402,8 @@ player_t &player_t::operator=(const player_t &p)
|
|||
ConversationPC = p.ConversationPC;
|
||||
ConversationNPCAngle = p.ConversationNPCAngle;
|
||||
ConversationFaceTalker = p.ConversationFaceTalker;
|
||||
MUSINFOactor = p.MUSINFOactor;
|
||||
MUSINFOtics = p.MUSINFOtics;
|
||||
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 (*&ConversationNPC == old) ConversationNPC = replacement, changed++;
|
||||
if (*&ConversationPC == old) ConversationPC = replacement, changed++;
|
||||
if (*&MUSINFOactor == old) MUSINFOactor = replacement, changed++;
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
@ -443,6 +448,7 @@ size_t player_t::PropagateMark()
|
|||
GC::Mark(ReadyWeapon);
|
||||
GC::Mark(ConversationNPC);
|
||||
GC::Mark(ConversationPC);
|
||||
GC::Mark(MUSINFOactor);
|
||||
GC::Mark(PremorphWeapon);
|
||||
if (PendingWeapon != WP_NOCHANGE)
|
||||
{
|
||||
|
@ -2331,6 +2337,30 @@ void P_PlayerThink (player_t *player)
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -3105,6 +3135,10 @@ void player_t::Serialize (FArchive &arc)
|
|||
{
|
||||
userinfo.SkinChanged(skinname, CurrentPlayerClass);
|
||||
}
|
||||
if (SaveVersion >= 4522)
|
||||
{
|
||||
arc << MUSINFOactor << MUSINFOtics;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1359,6 +1359,11 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_
|
|||
{
|
||||
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
|
||||
// colormap, disable acceleration so that the lights can remain fixed.
|
||||
if (!noaccel && realfixedcolormap == NULL &&
|
||||
|
|
|
@ -2348,7 +2348,6 @@ class AMusicChanger : public ASectorAction
|
|||
DECLARE_CLASS (AMusicChanger, ASectorAction)
|
||||
public:
|
||||
virtual bool DoTriggerAction (AActor *triggerer, int activationType);
|
||||
virtual void Tick();
|
||||
virtual void PostBeginPlay();
|
||||
};
|
||||
|
||||
|
@ -2356,49 +2355,27 @@ IMPLEMENT_CLASS(AMusicChanger)
|
|||
|
||||
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]))
|
||||
{
|
||||
level.nextmusic = args[0];
|
||||
reactiontime = 30;
|
||||
if (triggerer->player->MUSINFOactor != this)
|
||||
{
|
||||
triggerer->player->MUSINFOactor = this;
|
||||
triggerer->player->MUSINFOtics = 30;
|
||||
}
|
||||
}
|
||||
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()
|
||||
{
|
||||
// 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.
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ static FRandom pr_animatepictures ("AnimatePics");
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTextureManager::AddAnim (FAnimDef *anim)
|
||||
FAnimDef *FTextureManager::AddAnim (FAnimDef *anim)
|
||||
{
|
||||
// Search for existing duplicate.
|
||||
for (unsigned int i = 0; i < mAnimations.Size(); ++i)
|
||||
|
@ -78,11 +78,12 @@ void FTextureManager::AddAnim (FAnimDef *anim)
|
|||
// Found one!
|
||||
free (mAnimations[i]);
|
||||
mAnimations[i] = anim;
|
||||
return;
|
||||
return anim;
|
||||
}
|
||||
}
|
||||
// Didn't find one, so add it at the end.
|
||||
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)))
|
||||
{
|
||||
|
@ -102,13 +103,15 @@ void FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, int animt
|
|||
anim->CurFrame = 0;
|
||||
anim->BasePic = picnum;
|
||||
anim->NumFrames = animcount;
|
||||
anim->AnimType = animtype;
|
||||
anim->AnimType = FAnimDef::ANIM_Forward;
|
||||
anim->bDiscrete = false;
|
||||
anim->SwitchTime = 0;
|
||||
anim->Frames[0].SpeedMin = speedmin;
|
||||
anim->Frames[0].SpeedRange = speedrange;
|
||||
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]));
|
||||
anim->BasePic = picnum;
|
||||
anim->NumFrames = frames.Size();
|
||||
anim->CurFrame = 0;
|
||||
anim->AnimType = FAnimDef::ANIM_DiscreteFrames;
|
||||
anim->AnimType = FAnimDef::ANIM_Forward;
|
||||
anim->bDiscrete = true;
|
||||
anim->SwitchTime = 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.
|
||||
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;
|
||||
int defined = 0;
|
||||
bool optional = false, missing = false;
|
||||
FAnimDef *ani = NULL;
|
||||
BYTE type = FAnimDef::ANIM_Forward;
|
||||
|
||||
sc.MustGetString ();
|
||||
if (sc.Compare ("optional"))
|
||||
|
@ -370,6 +377,22 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
|
|||
}
|
||||
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"))
|
||||
{
|
||||
if (defined == 2)
|
||||
|
@ -381,7 +404,7 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
|
|||
sc.ScriptError ("You can only use one \"range\" per animation.");
|
||||
}
|
||||
defined = 1;
|
||||
ParseRangeAnim (sc, picnum, usetype, missing);
|
||||
ani = ParseRangeAnim (sc, picnum, usetype, missing);
|
||||
}
|
||||
else if (sc.Compare ("pic"))
|
||||
{
|
||||
|
@ -407,7 +430,12 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
|
|||
{
|
||||
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;
|
||||
FTextureID framenum;
|
||||
|
@ -432,7 +460,7 @@ void FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usety
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -440,18 +468,9 @@ void FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usety
|
|||
Texture(framenum)->bNoDecals = Texture(picnum)->bNoDecals;
|
||||
swapvalues (framenum, picnum);
|
||||
}
|
||||
if (sc.GetString())
|
||||
{
|
||||
if (sc.Compare ("Oscillate"))
|
||||
{
|
||||
type = type == FAnimDef::ANIM_Forward ? FAnimDef::ANIM_OscillateUp : FAnimDef::ANIM_OscillateDown;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.UnGet ();
|
||||
}
|
||||
}
|
||||
AddSimpleAnim (picnum, framenum - picnum + 1, type, min, max - min);
|
||||
FAnimDef *ani = AddSimpleAnim (picnum, framenum - picnum + 1, min, max - min);
|
||||
if (ani != NULL) ani->AnimType = type;
|
||||
return ani;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -691,7 +710,7 @@ void FTextureManager::FixAnimations ()
|
|||
for (i = 0; i < mAnimations.Size(); ++i)
|
||||
{
|
||||
FAnimDef *anim = mAnimations[i];
|
||||
if (anim->AnimType == FAnimDef::ANIM_DiscreteFrames)
|
||||
if (anim->bDiscrete)
|
||||
{
|
||||
if (Texture(anim->BasePic)->bNoRemap0)
|
||||
{
|
||||
|
@ -830,7 +849,7 @@ FDoorAnimation *FTextureManager::FindAnimatedDoor (FTextureID picnum)
|
|||
|
||||
void FAnimDef::SetSwitchTime (DWORD mstime)
|
||||
{
|
||||
int speedframe = (AnimType == FAnimDef::ANIM_DiscreteFrames) ? CurFrame : 0;
|
||||
int speedframe = bDiscrete ? CurFrame : 0;
|
||||
|
||||
SwitchTime = mstime + Frames[speedframe].SpeedMin;
|
||||
if (Frames[speedframe].SpeedRange != 0)
|
||||
|
@ -889,7 +908,6 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
|
|||
{
|
||||
default:
|
||||
case FAnimDef::ANIM_Forward:
|
||||
case FAnimDef::ANIM_DiscreteFrames:
|
||||
anim->CurFrame = (anim->CurFrame + 1) % anim->NumFrames;
|
||||
break;
|
||||
|
||||
|
@ -904,6 +922,16 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
|
|||
}
|
||||
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:
|
||||
anim->CurFrame = anim->CurFrame + 1;
|
||||
if (anim->CurFrame >= anim->NumFrames - 1)
|
||||
|
@ -923,7 +951,7 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
|
|||
anim->SetSwitchTime (mstime);
|
||||
}
|
||||
|
||||
if (anim->AnimType == FAnimDef::ANIM_DiscreteFrames)
|
||||
if (anim->bDiscrete)
|
||||
{
|
||||
SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic);
|
||||
}
|
||||
|
|
|
@ -1245,6 +1245,12 @@ void FTextureManager::PrecacheLevel (void)
|
|||
memset (hitlist, 0, cnt);
|
||||
|
||||
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--)
|
||||
{
|
||||
Renderer->PrecacheTexture(ByIndex(i), hitlist[i]);
|
||||
|
|
|
@ -87,6 +87,7 @@ struct FAnimDef
|
|||
WORD NumFrames;
|
||||
WORD CurFrame;
|
||||
BYTE AnimType;
|
||||
bool bDiscrete; // taken out of AnimType to have better control
|
||||
DWORD SwitchTime; // Time to advance to next frame
|
||||
struct FAnimFrame
|
||||
{
|
||||
|
@ -100,7 +101,7 @@ struct FAnimDef
|
|||
ANIM_Backward,
|
||||
ANIM_OscillateUp,
|
||||
ANIM_OscillateDown,
|
||||
ANIM_DiscreteFrames
|
||||
ANIM_Random
|
||||
};
|
||||
|
||||
void SetSwitchTime (DWORD mstime);
|
||||
|
@ -493,14 +494,14 @@ private:
|
|||
void InitBuildTiles ();
|
||||
|
||||
// Animation stuff
|
||||
void AddAnim (FAnimDef *anim);
|
||||
FAnimDef *AddAnim (FAnimDef *anim);
|
||||
void FixAnimations ();
|
||||
void InitAnimated ();
|
||||
void InitAnimDefs ();
|
||||
void AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD speedmin, DWORD speedrange=0);
|
||||
void AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames);
|
||||
FAnimDef *AddSimpleAnim (FTextureID picnum, int animcount, DWORD speedmin, DWORD speedrange=0);
|
||||
FAnimDef *AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames);
|
||||
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 ParseWarp(FScanner &sc);
|
||||
void ParseCameraTexture(FScanner &sc);
|
||||
|
|
|
@ -5186,15 +5186,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed)
|
|||
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();
|
||||
return (!(filter) || (filter == NULL) || (filter && ((exclude) ? (c1 != filter) : (c1 == filter))));
|
||||
const PClass *actorClass = mo->GetClass();
|
||||
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)
|
||||
{
|
||||
bool filterpass = DoCheckFilter(dmgtarget, filter, (flags & DMSS_EXFILTER) ? true : false),
|
||||
speciespass = DoCheckSpecies(dmgtarget, species, (flags & DMSS_EXSPECIES) ? true : false);
|
||||
bool filterpass = DoCheckClass(dmgtarget, filter, !!(flags & DMSS_EXFILTER)),
|
||||
speciespass = DoCheckSpecies(dmgtarget, species, !!(flags & DMSS_EXSPECIES));
|
||||
if ((flags & DMSS_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass))
|
||||
{
|
||||
int dmgFlags = 0;
|
||||
if (flags & DMSS_FOILINVUL)
|
||||
dmgFlags += DMG_FOILINVUL;
|
||||
dmgFlags |= DMG_FOILINVUL;
|
||||
if (flags & DMSS_FOILBUDDHA)
|
||||
dmgFlags += DMG_FOILBUDDHA;
|
||||
if ((flags & DMSS_KILL) || (flags & DMSS_NOFACTOR)) //Kill implies NoFactor
|
||||
dmgFlags += DMG_NO_FACTOR;
|
||||
dmgFlags |= DMG_FOILBUDDHA;
|
||||
if (flags & (DMSS_KILL | DMSS_NOFACTOR)) //Kill implies NoFactor
|
||||
dmgFlags |= DMG_NO_FACTOR;
|
||||
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.
|
||||
amount += dmgtarget->health;
|
||||
if (flags & DMSS_NOPROTECT) //Ignore PowerProtection.
|
||||
dmgFlags += DMG_NO_PROTECT;
|
||||
dmgFlags |= DMG_NO_PROTECT;
|
||||
|
||||
if (amount > 0)
|
||||
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)
|
||||
{
|
||||
bool filterpass = DoCheckFilter(killtarget, filter, (flags & KILS_EXFILTER) ? true : false),
|
||||
speciespass = DoCheckSpecies(killtarget, species, (flags & KILS_EXSPECIES) ? true : false);
|
||||
bool filterpass = DoCheckClass(killtarget, filter, !!(flags & KILS_EXFILTER)),
|
||||
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.
|
||||
{
|
||||
int dmgFlags = DMG_NO_ARMOR + DMG_NO_FACTOR;
|
||||
int dmgFlags = DMG_NO_ARMOR | DMG_NO_FACTOR;
|
||||
|
||||
if (KILS_FOILINVUL)
|
||||
dmgFlags += DMG_FOILINVUL;
|
||||
dmgFlags |= DMG_FOILINVUL;
|
||||
if (KILS_FOILBUDDHA)
|
||||
dmgFlags += DMG_FOILBUDDHA;
|
||||
dmgFlags |= DMG_FOILBUDDHA;
|
||||
|
||||
|
||||
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
|
||||
//since that's the whole point of it.
|
||||
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);
|
||||
}
|
||||
|
@ -5568,8 +5572,8 @@ enum RMVF_flags
|
|||
|
||||
static void DoRemove(AActor *removetarget, int flags, const PClass *filter, FName species)
|
||||
{
|
||||
bool filterpass = DoCheckFilter(removetarget, filter, (flags & RMVF_EXFILTER) ? true : false),
|
||||
speciespass = DoCheckSpecies(removetarget, species, (flags & RMVF_EXSPECIES) ? true : false);
|
||||
bool filterpass = DoCheckClass(removetarget, filter, !!(flags & RMVF_EXFILTER)),
|
||||
speciespass = DoCheckSpecies(removetarget, species, !!(flags & RMVF_EXSPECIES));
|
||||
if ((flags & RMVF_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass))
|
||||
{
|
||||
if ((flags & RMVF_EVERYTHING))
|
||||
|
@ -5722,33 +5726,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Remove)
|
|||
// A_SetTeleFog
|
||||
//
|
||||
// Sets the teleport fog(s) for the calling actor.
|
||||
// Takes a name of the classes for te source and destination.
|
||||
// Can set both at the same time. Use "" to retain the previous fog without
|
||||
// changing it.
|
||||
// Takes a name of the classes for the source and destination.
|
||||
//===========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTeleFog)
|
||||
{
|
||||
ACTION_PARAM_START(2);
|
||||
ACTION_PARAM_NAME(oldpos, 0);
|
||||
ACTION_PARAM_NAME(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;
|
||||
ACTION_PARAM_CLASS(oldpos, 0);
|
||||
ACTION_PARAM_CLASS(newpos, 1);
|
||||
|
||||
check = PClass::FindClass(newpos);
|
||||
if (check == NULL || !stricmp(newpos, "none") || !stricmp(newpos, "null"))
|
||||
self->TeleFogDestType = NULL;
|
||||
else if (!stricmp(newpos, ""))
|
||||
{ //Don't change it if it's just ""
|
||||
}
|
||||
else
|
||||
self->TeleFogDestType = check;
|
||||
self->TeleFogSourceType = oldpos;
|
||||
self->TeleFogDestType = newpos;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -1422,7 +1422,7 @@ DEFINE_PROPERTY(stamina, I, Actor)
|
|||
DEFINE_PROPERTY(telefogsourcetype, S, Actor)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -1432,7 +1432,7 @@ DEFINE_PROPERTY(telefogsourcetype, S, Actor)
|
|||
DEFINE_PROPERTY(telefogdesttype, S, Actor)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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 4521
|
||||
#define SAVEVER 4522
|
||||
|
||||
#define SAVEVERSTRINGIFY2(x) #x
|
||||
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "doomerrors.h"
|
||||
#include "resourcefiles/resourcefile.h"
|
||||
#include "md5.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -300,6 +301,56 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadinfo)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -561,37 +561,26 @@ void I_DetectOS(void)
|
|||
{
|
||||
if (info.dwMinorVersion == 0)
|
||||
{
|
||||
if (info.wProductType == VER_NT_WORKSTATION)
|
||||
{
|
||||
osname = "Vista";
|
||||
}
|
||||
else
|
||||
{
|
||||
osname = "Server 2008";
|
||||
}
|
||||
osname = (info.wProductType == VER_NT_WORKSTATION) ? "Vista" : "Server 2008";
|
||||
}
|
||||
else if (info.dwMinorVersion == 1)
|
||||
{
|
||||
if (info.wProductType == VER_NT_WORKSTATION)
|
||||
{
|
||||
osname = "7";
|
||||
}
|
||||
else
|
||||
{
|
||||
osname = "Server 2008 R2";
|
||||
}
|
||||
osname = (info.wProductType == VER_NT_WORKSTATION) ? "7" : "Server 2008 R2";
|
||||
}
|
||||
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.
|
||||
if (info.wProductType == VER_NT_WORKSTATION)
|
||||
{
|
||||
osname = "8 (or higher)";
|
||||
}
|
||||
else
|
||||
{
|
||||
osname = "Server 2012 (or higher)";
|
||||
}
|
||||
// Starting with Windows 8.1, you need to specify in your manifest
|
||||
// the highest version of Windows you support, which will also be the
|
||||
// highest version of Windows this function returns.
|
||||
osname = (info.wProductType == VER_NT_WORKSTATION) ? "8" : "Server 2012";
|
||||
}
|
||||
else if (info.dwMinorVersion == 3)
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -5,4 +5,23 @@
|
|||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
|
||||
</dependentAssembly>
|
||||
</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>
|
|
@ -25,8 +25,7 @@ if( NOT CMAKE_CROSSCOMPILING )
|
|||
endif( NOT CMAKE_CROSSCOMPILING )
|
||||
|
||||
if( MT_MERGE )
|
||||
get_target_property( UPDATEREVISION_EXE updaterevision LOCATION )
|
||||
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" )
|
||||
endif( MT_MERGE )
|
||||
|
|
|
@ -325,7 +325,7 @@ ACTOR Actor native //: Thinker
|
|||
action native A_GiveToSiblings(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_SetTeleFog(name oldpos, name newpos);
|
||||
action native A_SetTeleFog(class<TeleportFog> oldpos, class<TeleportFog> newpos);
|
||||
action native A_SwapTeleFog();
|
||||
action native A_SetFloatBobPhase(int bob);
|
||||
action native A_SetHealth(int health, int ptr = AAPTR_DEFAULT);
|
||||
|
|
|
@ -124,6 +124,14 @@ BA530202AF0BA0C6CBAE6A0C7076FB72 // Requiem map04
|
|||
3CA5493FEFF2E27BFD4181E6C4A3C2BF // The Waterfront map01
|
||||
CBDFEFAC579A62DE8F1B48CA4A09D381 // gather2.wad map05 and darkside.wad map01
|
||||
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
|
||||
vileghosts
|
||||
|
|
20
zdoom.vcproj
20
zdoom.vcproj
|
@ -117,6 +117,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
AdditionalManifestFiles="src\win32\zdoom.exe.manifest"
|
||||
SuppressStartupBanner="true"
|
||||
AssemblyIdentity=""
|
||||
/>
|
||||
|
@ -233,6 +234,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
AdditionalManifestFiles="src\win32\zdoom.exe.manifest"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
|
@ -339,6 +341,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
AdditionalManifestFiles="src\win32\zdoom.exe.manifest"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
|
@ -446,6 +449,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
AdditionalManifestFiles="src\win32\zdoom.exe.manifest"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
|
@ -2616,6 +2620,14 @@
|
|||
RelativePath=".\src\oplsynth\muslib.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\oplsynth\nukedopl3.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\oplsynth\nukedopl3.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\oplsynth\opl.h"
|
||||
>
|
||||
|
@ -2632,14 +2644,6 @@
|
|||
RelativePath=".\src\oplsynth\opl_mus_player.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\oplsynth\nukedopl3.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\oplsynth\nukedopl3.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="DOSBox"
|
||||
>
|
||||
|
|
Loading…
Reference in a new issue