diff --git a/CMakeLists.txt b/CMakeLists.txt index 22bc0e7cc..0858ecab5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,39 @@ cmake_minimum_required( VERSION 2.4 ) project(ZDoom) +# Generator expression are available some time in CMake 2.8. Due to +# cmake_minimum_required, we can assume a minor version of > 7 implies major >= 2 +if(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7) + option( NO_GENERATOR_EXPRESSIONS "Disable generator expressions (for building pk3s with IDEs)." OFF ) +else(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7) + set( NO_GENERATOR_EXPRESSIONS ON ) +endif(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7) + +# Simplify pk3 building, add_pk3(filename srcdirectory) +function( add_pk3 PK3_NAME PK3_DIR ) + get_target_property(ZIPDIR_EXE zipdir LOCATION) + + # Generate target name. Just use "pk3" for main pk3 target. + string( REPLACE "." "_" PK3_TARGET ${PK3_NAME} ) + if( ${PK3_TARGET} STREQUAL "zdoom_pk3" ) + set( PK3_TARGET "pk3" ) + endif( ${PK3_TARGET} STREQUAL "zdoom_pk3" ) + + if( NO_GENERATOR_EXPRESSIONS ) + add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} + COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $ + DEPENDS zipdir ${PK3_DIR} ) + else( NO_GENERATOR_EXPRESSIONS ) + add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} + COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} + DEPENDS zipdir ${PK3_DIR} ) + endif( NO_GENERATOR_EXPRESSIONS ) + + add_custom_target( ${PK3_TARGET} ALL + DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ) +endfunction( add_pk3 ) + IF( NOT CMAKE_BUILD_TYPE ) SET( CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c36c9a393..ee814c138 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,7 +9,12 @@ include( CheckFunctionExists ) include( CheckCXXCompilerFlag ) include( FindPkgConfig ) -option( NO_ASM "Disable assembly code" ) +if( NOT APPLE ) + option( NO_ASM "Disable assembly code" OFF ) +else( NOT APPLE ) + # At the moment asm code doesn't work with OS X, so disable by default + option( NO_ASM "Disable assembly code" ON ) +endif( NOT APPLE ) if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) option( NO_STRIP "Do not strip Release or MinSizeRel builds" ) # At least some versions of Xcode fail if you strip with the linker diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 25b6978da..ada1f93ba 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -958,8 +958,8 @@ CCMD(nextmap) { if (netgame) { - Printf ("Use "TEXTCOLOR_BOLD"changemap"TEXTCOLOR_NORMAL" instead. "TEXTCOLOR_BOLD"Nextmap" - TEXTCOLOR_NORMAL" is for single-player only.\n"); + Printf ("Use " TEXTCOLOR_BOLD "changemap" TEXTCOLOR_NORMAL " instead. " TEXTCOLOR_BOLD "Nextmap" + TEXTCOLOR_NORMAL " is for single-player only.\n"); return; } char *next = NULL; @@ -986,8 +986,8 @@ CCMD(nextsecret) { if (netgame) { - Printf ("Use "TEXTCOLOR_BOLD"changemap"TEXTCOLOR_NORMAL" instead. "TEXTCOLOR_BOLD"Nextsecret" - TEXTCOLOR_NORMAL" is for single-player only.\n"); + Printf ("Use " TEXTCOLOR_BOLD "changemap" TEXTCOLOR_NORMAL " instead. " TEXTCOLOR_BOLD "Nextsecret" + TEXTCOLOR_NORMAL " is for single-player only.\n"); return; } char *next = NULL; diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 7b701bd53..d25354986 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -92,8 +92,8 @@ private: struct FActionMap { - unsigned int Key; // value from passing Name to MakeKey() FButtonStatus *Button; + unsigned int Key; // value from passing Name to MakeKey() char Name[12]; }; @@ -134,38 +134,38 @@ bool ParsingKeyConf; FActionMap ActionMaps[] = { - { 0x0d52d67b, &Button_AM_PanLeft, "am_panleft"}, - { 0x125f5226, &Button_User2, "user2" }, - { 0x1eefa611, &Button_Jump, "jump" }, - { 0x201f1c55, &Button_Right, "right" }, - { 0x20ccc4d5, &Button_Zoom, "zoom" }, - { 0x23a99cd7, &Button_Back, "back" }, - { 0x41df90c2, &Button_AM_ZoomIn, "am_zoomin"}, - { 0x426b69e7, &Button_Reload, "reload" }, - { 0x4463f43a, &Button_LookDown, "lookdown" }, - { 0x51f7a334, &Button_AM_ZoomOut, "am_zoomout"}, - { 0x534c30ee, &Button_User4, "user4" }, - { 0x5622bf42, &Button_Attack, "attack" }, - { 0x577712d0, &Button_User1, "user1" }, - { 0x57c25cb2, &Button_Klook, "klook" }, - { 0x59f3e907, &Button_Forward, "forward" }, - { 0x6167ce99, &Button_MoveDown, "movedown" }, - { 0x676885b8, &Button_AltAttack, "altattack" }, - { 0x6fa41b84, &Button_MoveLeft, "moveleft" }, - { 0x818f08e6, &Button_MoveRight, "moveright" }, - { 0x8197097b, &Button_AM_PanRight, "am_panright"}, - { 0x8d89955e, &Button_AM_PanUp, "am_panup"} , - { 0xa2b62d8b, &Button_Mlook, "mlook" }, - { 0xab2c3e71, &Button_Crouch, "crouch" }, - { 0xb000b483, &Button_Left, "left" }, - { 0xb62b1e49, &Button_LookUp, "lookup" }, - { 0xb6f8fe92, &Button_User3, "user3" }, - { 0xb7e6a54b, &Button_Strafe, "strafe" }, - { 0xce301c81, &Button_AM_PanDown, "am_pandown"}, - { 0xd5897c73, &Button_ShowScores, "showscores" }, - { 0xe0ccb317, &Button_Speed, "speed" }, - { 0xe0cfc260, &Button_Use, "use" }, - { 0xfdd701c7, &Button_MoveUp, "moveup" }, + { &Button_AM_PanLeft, 0x0d52d67b, "am_panleft"}, + { &Button_User2, 0x125f5226, "user2" }, + { &Button_Jump, 0x1eefa611, "jump" }, + { &Button_Right, 0x201f1c55, "right" }, + { &Button_Zoom, 0x20ccc4d5, "zoom" }, + { &Button_Back, 0x23a99cd7, "back" }, + { &Button_AM_ZoomIn, 0x41df90c2, "am_zoomin"}, + { &Button_Reload, 0x426b69e7, "reload" }, + { &Button_LookDown, 0x4463f43a, "lookdown" }, + { &Button_AM_ZoomOut, 0x51f7a334, "am_zoomout"}, + { &Button_User4, 0x534c30ee, "user4" }, + { &Button_Attack, 0x5622bf42, "attack" }, + { &Button_User1, 0x577712d0, "user1" }, + { &Button_Klook, 0x57c25cb2, "klook" }, + { &Button_Forward, 0x59f3e907, "forward" }, + { &Button_MoveDown, 0x6167ce99, "movedown" }, + { &Button_AltAttack, 0x676885b8, "altattack" }, + { &Button_MoveLeft, 0x6fa41b84, "moveleft" }, + { &Button_MoveRight, 0x818f08e6, "moveright" }, + { &Button_AM_PanRight, 0x8197097b, "am_panright"}, + { &Button_AM_PanUp, 0x8d89955e, "am_panup"} , + { &Button_Mlook, 0xa2b62d8b, "mlook" }, + { &Button_Crouch, 0xab2c3e71, "crouch" }, + { &Button_Left, 0xb000b483, "left" }, + { &Button_LookUp, 0xb62b1e49, "lookup" }, + { &Button_User3, 0xb6f8fe92, "user3" }, + { &Button_Strafe, 0xb7e6a54b, "strafe" }, + { &Button_AM_PanDown, 0xce301c81, "am_pandown"}, + { &Button_ShowScores, 0xd5897c73, "showscores" }, + { &Button_Speed, 0xe0ccb317, "speed" }, + { &Button_Use, 0xe0cfc260, "use" }, + { &Button_MoveUp, 0xfdd701c7, "moveup" }, }; #define NUM_ACTIONS countof(ActionMaps) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 4a4f19d6b..7bbff7322 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -105,6 +105,7 @@ static FCompatOption Options[] = { "vileghosts", BCOMPATF_VILEGHOSTS, SLOT_BCOMPAT }, { "ignoreteleporttags", BCOMPATF_BADTELEPORTERS, SLOT_BCOMPAT }, { "rebuildnodes", BCOMPATF_REBUILDNODES, SLOT_BCOMPAT }, + { "linkfrozenprops", BCOMPATF_LINKFROZENPROPS, SLOT_BCOMPAT }, // list copied from g_mapinfo.cpp { "shorttex", COMPATF_SHORTTEX, SLOT_COMPAT }, diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index e53a1d362..6b430fa03 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -367,7 +367,7 @@ int FIWadManager::CheckIWAD (const char *doomwaddir, WadStuff *wads) // Under UNIX OSes, the search path is: // 1. Current directory // 2. $DOOMWADDIR -// 3. $HOME/.zdoom +// 3. $HOME/.config/zdoom // 4. The share directory defined at compile time (/usr/local/share/zdoom) // // The search path can be altered by editing the IWADSearch.Directories @@ -516,9 +516,19 @@ int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, I_FatalError ("Cannot find a game IWAD (doom.wad, doom2.wad, heretic.wad, etc.).\n" "Did you install ZDoom properly? You can do either of the following:\n" "\n" +#if defined(_WIN32) "1. Place one or more of these wads in the same directory as ZDoom.\n" "2. Edit your zdoom-username.ini and add the directories of your iwads\n" "to the list beneath [IWADSearch.Directories]"); +#elif defined(__APPLE__) + "1. Place one or more of these wads in ~/Library/Application Support/zdoom/\n" + "2. Edit your ~/Library/Preferences/zdoom.ini and add the directories\n" + "of your iwads to the list beneath [IWADSearch.Directories]"); +#else + "1. Place one or more of these wads in ~/.config/zdoom/.\n" + "2. Edit your ~/.config/zdoom/zdoom.ini and add the directories of your\n" + "iwads to the list beneath [IWADSearch.Directories]"); +#endif } pickwad = 0; diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 2499a03f8..8101c5248 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -713,7 +713,7 @@ void D_WriteUserInfoStrings (int pnum, BYTE **stream, bool compact) if (!compact) { // In verbose mode, prepend the cvar's name - *stream += sprintf(*((char **)stream), "\\%s\\", pair->Key.GetChars()); + *stream += sprintf(*((char **)stream), "\\%s", pair->Key.GetChars()); } // A few of these need special handling for compatibility reasons. switch (pair->Key.GetIndex()) @@ -1048,3 +1048,14 @@ CCMD (playerinfo) } } } + +userinfo_t::~userinfo_t() +{ + TMapIterator it(*this); + TMap::Pair *pair; + + while (it.NextPair(pair)) + { + delete pair->Value; + } +} diff --git a/src/d_player.h b/src/d_player.h index 260cf37dc..839ea1b6e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -160,6 +160,7 @@ public: int SpawnMask; FNameNoInit MorphWeapon; fixed_t AttackZOffset; // attack height, relative to player center + fixed_t UseRange; // [NS] Distance at which player can +use PClassActor *FlechetteType; // [CW] Fades for when you are being damaged. @@ -280,6 +281,8 @@ enum struct userinfo_t : TMap { + ~userinfo_t(); + int GetAimDist() const { if (dmflags2 & DF2_NOAUTOAIM) diff --git a/src/doomdef.h b/src/doomdef.h index 3a3c31e6a..675923b4a 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -349,6 +349,7 @@ enum BCOMPATF_BADTELEPORTERS = 1 << 3, // Ignore tags on Teleport specials BCOMPATF_BADPORTALS = 1 << 4, // Restores the old unstable portal behavior BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild + BCOMPATF_LINKFROZENPROPS = 1 << 6, // Clearing PROP_TOTALLYFROZEN or PROP_FROZEN also clears the other }; // phares 3/20/98: diff --git a/src/g_level.cpp b/src/g_level.cpp index 755a4fba6..a452d5576 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -164,8 +164,8 @@ CCMD (map) { if (netgame) { - Printf ("Use "TEXTCOLOR_BOLD"changemap"TEXTCOLOR_NORMAL" instead. "TEXTCOLOR_BOLD"Map" - TEXTCOLOR_NORMAL" is for single-player only.\n"); + Printf ("Use " TEXTCOLOR_BOLD "changemap" TEXTCOLOR_NORMAL " instead. " TEXTCOLOR_BOLD "Map" + TEXTCOLOR_NORMAL " is for single-player only.\n"); return; } if (argv.argc() > 1) diff --git a/src/g_shared/sbar_mugshot.cpp b/src/g_shared/sbar_mugshot.cpp index fcf5642de..09045cd57 100644 --- a/src/g_shared/sbar_mugshot.cpp +++ b/src/g_shared/sbar_mugshot.cpp @@ -352,11 +352,8 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags) SetState("grin", false); return 0; } - else if (CurrentState == NULL) - { - bEvilGrin = false; - } } + bEvilGrin = false; bool ouch = (!st_oldouch && FaceHealth - player->health > ST_MUCHPAIN) || (st_oldouch && player->health - FaceHealth > ST_MUCHPAIN); if (player->damagecount && diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 99ac59938..20779a221 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -898,7 +898,7 @@ IMPLEMENT_CLASS(DSaveMenu) DSaveMenu::DSaveMenu(DMenu *parent, FListMenuDescriptor *desc) : DLoadSaveMenu(parent, desc) { - strcpy (NewSaveNode.Title, ""); + strcpy (NewSaveNode.Title, GStrings["NEWSAVE"]); NewSaveNode.bNoDelete = true; SaveGames.Insert(0, &NewSaveNode); TopItem = 0; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 5b733f029..585c8e63d 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -112,6 +112,9 @@ FRandom pr_acs ("ACS"); #define NOT_FLOOR 8 #define NOT_CEILING 16 +// LineAtack flags +#define FHF_NORANDOMPUFFZ 1 + // SpawnDecal flags #define SDF_ABSANGLE 1 #define SDF_PERMANENT 2 @@ -4961,10 +4964,13 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const FName pufftype = argCount > 4 && args[4]? FName(FBehavior::StaticLookupString(args[4])) : NAME_BulletPuff; FName damagetype = argCount > 5 && args[5]? FName(FBehavior::StaticLookupString(args[5])) : NAME_None; fixed_t range = argCount > 6 && args[6]? args[6] : MISSILERANGE; + int flags = argCount > 7 && args[7]? args[7] : 0; + + int fhflags = (flags & FHF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; if (args[0] == 0) { - P_LineAttack(activator, angle, range, pitch, damage, damagetype, pufftype); + P_LineAttack(activator, angle, range, pitch, damage, damagetype, pufftype, fhflags); } else { @@ -4973,7 +4979,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const while ((source = it.Next()) != NULL) { - P_LineAttack(activator, angle, range, pitch, damage, damagetype, pufftype); + P_LineAttack(activator, angle, range, pitch, damage, damagetype, pufftype, fhflags); } } } @@ -5020,7 +5026,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) { S_Sound(spot, chan, sid, vol, atten); } - else if (!S_IsActorPlayingSomething(spot, chan, sid)) + else if (!S_IsActorPlayingSomething(spot, chan & 7, sid)) { S_Sound(spot, chan | CHAN_LOOP, sid, vol, atten); } @@ -5551,7 +5557,8 @@ int DLevelScript::RunScript () case PCD_PUSHFUNCTION: { int funcnum = NEXTBYTE; - PushToStack(funcnum | activeBehavior->GetLibraryID()); + // Not technically a string, but since we use the same tagging mechanism + PushToStack(TAGSTR(funcnum)); break; } case PCD_CALL: @@ -5567,7 +5574,7 @@ int DLevelScript::RunScript () if(pcd == PCD_CALLSTACK) { funcnum = STACK(1); - module = FBehavior::StaticGetModule(funcnum>>16); + module = FBehavior::StaticGetModule(funcnum>>LIBRARYID_SHIFT); --sp; funcnum &= 0xFFFF; // Clear out tag @@ -8444,7 +8451,8 @@ scriptwait: case PCD_SAVESTRING: // Saves the string { - PushToStack(GlobalACSStrings.AddString(work, Stack, sp)); + const int str = GlobalACSStrings.AddString(work, Stack, sp); + PushToStack(str); STRINGBUILDER_FINISH(work); } break; diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 7a14e4d44..2665f69ba 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -252,7 +252,7 @@ static bool LoadGLVertexes(FileReader * lump) // GLNodes V1 and V4 are unsupported. // V1 because the precision is insufficient and // V4 due to the missing partner segs - Printf("GL nodes v%d found. This format is not supported by "GAMENAME"\n", + Printf("GL nodes v%d found. This format is not supported by " GAMENAME "\n", (*(int *)gldata == gNd4)? 4:1); delete [] gldata; diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 30bef7a99..898b30278 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -652,10 +652,38 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) FState *diestate = NULL; + int gibhealth = GetGibHealth(); + int iflags4 = inflictor == NULL ? 0 : inflictor->flags4; + bool extremelydead = ((health < gibhealth || iflags4 & MF4_EXTREMEDEATH) && !(iflags4 & MF4_NOEXTREMEDEATH)); + + // Special check for 'extreme' damage type to ensure that it gets recorded properly as an extreme death for subsequent checks. + if (DamageType == NAME_Extreme) + { + extremelydead = true; + DamageType = NAME_None; + } + + // find the appropriate death state. The order is: + // + // 1. If damagetype is not 'none' and death is extreme, try a damage type specific extreme death state + // 2. If no such state is found or death is not extreme try a damage type specific normal death state + // 3. If damagetype is 'ice' and actor is a monster or player, try the generic freeze death (unless prohibited) + // 4. If no state has been found and death is extreme, try the extreme death state + // 5. If no such state is found or death is not extreme try the regular death state. + // 6. If still no state has been found, destroy the actor immediately. if (DamageType != NAME_None) { - diestate = FindState (NAME_Death, DamageType, true); + if (extremelydead) + { + FName labels[] = { NAME_Death, NAME_Extreme, DamageType }; + diestate = FindState(3, labels, true); + } + if (diestate == NULL) + { + diestate = FindState (NAME_Death, DamageType, true); + if (diestate != NULL) extremelydead = false; + } if (diestate == NULL) { if (DamageType == NAME_Ice) @@ -664,15 +692,13 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) if (!deh.NoAutofreeze && !(flags4 & MF4_NOICEDEATH) && (player || (flags3 & MF3_ISMONSTER))) { diestate = FindState(NAME_GenericFreezeDeath); + extremelydead = false; } } } } if (diestate == NULL) { - int flags4 = inflictor == NULL ? 0 : inflictor->flags4; - - int gibhealth = GetGibHealth(); // Don't pass on a damage type this actor cannot handle. // (most importantly, prevent barrels from passing on ice damage.) @@ -682,26 +708,33 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) DamageType = NAME_None; } - if ((health < gibhealth || flags4 & MF4_EXTREMEDEATH) && !(flags4 & MF4_NOEXTREMEDEATH)) + if (extremelydead) { // Extreme death diestate = FindState (NAME_Death, NAME_Extreme, true); - // If a non-player, mark as extremely dead for the crash state. - if (diestate != NULL && player == NULL && health >= gibhealth) - { - health = gibhealth - 1; - } - // For players, mark the appropriate flag. - else if (player != NULL) - { - player->cheats |= CF_EXTREMELYDEAD; - } } if (diestate == NULL) { // Normal death + extremelydead = false; diestate = FindState (NAME_Death); } } + if (extremelydead) + { + // We'll only get here if an actual extreme death state was used. + + // For players, mark the appropriate flag. + if (player != NULL) + { + player->cheats |= CF_EXTREMELYDEAD; + } + // If a non-player, mark as extremely dead for the crash state. + else if (health >= gibhealth) + { + health = gibhealth - 1; + } + } + if (diestate != NULL) { SetState (diestate); diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index ee6af8e9f..d6524f848 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2813,6 +2813,11 @@ FUNC(LS_SetPlayerProperty) { int i; + if ((ib_compatflags & BCOMPATF_LINKFROZENPROPS) && (mask & (CF_FROZEN | CF_TOTALLYFROZEN))) + { // Clearing one of these properties clears both of them (if the compat flag is set.) + mask = CF_FROZEN | CF_TOTALLYFROZEN; + } + for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) diff --git a/src/p_map.cpp b/src/p_map.cpp index 689f4ef19..f9c9b8087 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4362,14 +4362,17 @@ bool P_NoWayTraverse (AActor *usething, fixed_t endx, fixed_t endy) void P_UseLines (player_t *player) { angle_t angle; - fixed_t x1, y1; + fixed_t x1, y1, usedist; bool foundline; foundline = false; angle = player->mo->angle >> ANGLETOFINESHIFT; - x1 = player->mo->x + (USERANGE>>FRACBITS)*finecosine[angle]; - y1 = player->mo->y + (USERANGE>>FRACBITS)*finesine[angle]; + usedist = player->mo->UseRange; + + // [NS] Now queries the Player's UseRange. + x1 = player->mo->x + FixedMul(usedist, finecosine[angle]); + y1 = player->mo->y + FixedMul(usedist, finesine[angle]); // old code: // @@ -4401,13 +4404,20 @@ void P_UseLines (player_t *player) bool P_UsePuzzleItem (AActor *PuzzleItemUser, int PuzzleItemType) { int angle; - fixed_t x1, y1, x2, y2; + fixed_t x1, y1, x2, y2, usedist; angle = PuzzleItemUser->angle>>ANGLETOFINESHIFT; x1 = PuzzleItemUser->x; y1 = PuzzleItemUser->y; - x2 = x1+(USERANGE>>FRACBITS)*finecosine[angle]; - y2 = y1+(USERANGE>>FRACBITS)*finesine[angle]; + + // [NS] If it's a Player, get their UseRange. + if (PuzzleItemUser->player) + usedist = PuzzleItemUser->player->mo->UseRange; + else + usedist = USERANGE; + + x2 = x1 + FixedMul(usedist, finecosine[angle]); + y2 = y1 + FixedMul(usedist, finesine[angle]); FPathTraverse it(x1, y1, x2, y2, PT_ADDLINES|PT_ADDTHINGS); intercept_t *in; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 47dc3007f..f3fb9a55e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6029,7 +6029,15 @@ void AActor::Crash() if (DamageType != NAME_None) { - crashstate = FindState(NAME_Crash, DamageType, true); + if (health < GetGibHealth()) + { // Extreme death + FName labels[] = { NAME_Crash, NAME_Extreme, DamageType }; + crashstate = FindState (3, labels, true); + } + if (crashstate == NULL) + { // Normal death + crashstate = FindState(NAME_Crash, DamageType, true); + } } if (crashstate == NULL) { diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index a045c5098..bf0da0cbe 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -256,11 +256,19 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name) { // The userinfo needs to be saved for real players, but it // needs to come from the save for bots. - userinfo_t uibackup = dst->userinfo; + userinfo_t uibackup; + userinfo_t uibackup2; + + uibackup.TransferFrom(dst->userinfo); + uibackup2.TransferFrom(src->userinfo); + int chasecam = dst->cheats & CF_CHASECAM; // Remember the chasecam setting bool attackdown = dst->attackdown; bool usedown = dst->usedown; - *dst = *src; + + + *dst = *src; // To avoid memory leaks at this point the userinfo in src must be empty which is taken care of by the TransferFrom call above. + dst->cheats |= chasecam; if (dst->isbot) @@ -276,10 +284,11 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name) } bglobal.botnum++; bglobal.botingame[dst - players] = true; + dst->userinfo.TransferFrom(uibackup2); } else { - dst->userinfo = uibackup; + dst->userinfo.TransferFrom(uibackup); } // Validate the skin dst->userinfo.SkinNumChanged(R_FindSkin(skins[dst->userinfo.GetSkin()].name, dst->CurrentPlayerClass)); diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 2ec77fe2a..86977e197 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -639,12 +639,21 @@ void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, { next = actor->snext; // Only affect actors touching the 3D floor - if (actor->z + actor->height > sec->floorplane.ZatPoint(actor->x, actor->y)) + fixed_t z1 = sec->floorplane.ZatPoint(actor->x, actor->y); + fixed_t z2 = sec->ceilingplane.ZatPoint(actor->x, actor->y); + if (z2 < z1) + { + // Account for Vavoom-style 3D floors + fixed_t zz = z1; + z1 = z2; + z2 = zz; + } + if (actor->z + actor->height > z1) { // If DAMAGE_IN_AIR is used, anything not beneath the 3D floor will be // damaged (so, anything touching it or above it). Other 3D floors between // the actor and this one will not stop this effect. - if ((flags & DAMAGE_IN_AIR) || actor->z <= sec->ceilingplane.ZatPoint(actor->x, actor->y)) + if ((flags & DAMAGE_IN_AIR) || actor->z <= z2) { // Here we pass the DAMAGE_IN_AIR flag to disable the floor check, since it // only works with the real sector's floor. We did the appropriate height checks diff --git a/src/p_spec.h b/src/p_spec.h index 1e45c44ad..488a475d8 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -763,7 +763,7 @@ protected: fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt, int usespecials); friend bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, - fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower=false); + fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower); friend bool EV_FloorCrushStop (int tag); friend bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed); private: @@ -774,7 +774,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt, int usespecials); bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, - fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower); + fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower=false); bool EV_FloorCrushStop (int tag); bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed); diff --git a/src/p_user.cpp b/src/p_user.cpp index 6e9787d8f..0ace36a6b 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -308,7 +308,6 @@ player_t::player_t() ConversationFaceTalker(0) { memset (&cmd, 0, sizeof(cmd)); - memset (&userinfo, 0, sizeof(userinfo)); memset (frags, 0, sizeof(frags)); memset (psprites, 0, sizeof(psprites)); memset (&skill, 0, sizeof(skill)); @@ -557,6 +556,10 @@ void APlayerPawn::Serialize (FArchive &arc) { arc << GruntSpeed << FallingScreamMinSpeed << FallingScreamMaxSpeed; } + if (SaveVersion >= 4502) + { + arc << UseRange; + } } //=========================================================================== diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 8bf544455..986d99203 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -174,7 +174,15 @@ void R_InitPlanes () void R_DeinitPlanes () { fakeActive = 0; - R_ClearPlanes(false); + + // do not use R_ClearPlanes because at this point the screen pointer is no longer valid. + for (int i = 0; i <= MAXVISPLANES; i++) // new code -- killough + { + for (*freehead = visplanes[i], visplanes[i] = NULL; *freehead; ) + { + freehead = &(*freehead)->next; + } + } for (visplane_t *pl = freetail; pl != NULL; ) { visplane_t *next = pl->next; @@ -490,7 +498,7 @@ void R_MapColoredPlane (int y, int x1) void R_ClearPlanes (bool fullclear) { - int i, max; + int i; // Don't clear fake planes if not doing a full clear. if (!fullclear) @@ -516,7 +524,6 @@ void R_ClearPlanes (bool fullclear) } else { - max = fullclear ? MAXVISPLANES : MAXVISPLANES-1; for (i = 0; i <= MAXVISPLANES; i++) // new code -- killough { for (*freehead = visplanes[i], visplanes[i] = NULL; *freehead; ) @@ -524,10 +531,7 @@ void R_ClearPlanes (bool fullclear) freehead = &(*freehead)->next; } } - } - if (fullclear) - { // opening / clipping determination clearbufshort (floorclip, viewwidth, viewheight); // [RH] clip ceiling to console bottom diff --git a/src/r_utility.cpp b/src/r_utility.cpp index ffc10380a..ddc18145a 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -62,6 +62,9 @@ extern bool DrawFSHUD; // [RH] Defined in d_main.cpp EXTERN_CVAR (Bool, cl_capfps) +extern lighttable_t* fixedcolormap; +extern FSpecialColormap*realfixedcolormap; + // TYPES ------------------------------------------------------------------- struct InterpolationViewer @@ -1005,6 +1008,11 @@ void FCanvasTextureInfo::UpdateAll () { FCanvasTextureInfo *probe; + // curse Doom's overuse of global variables in the renderer. + // These get clobbered by rendering to a camera texture but they need to be preserved so the final rendering can be done with the correct palette. + unsigned char *savecolormap = fixedcolormap; + FSpecialColormap *savecm = realfixedcolormap; + for (probe = List; probe != NULL; probe = probe->Next) { if (probe->Viewpoint != NULL && probe->Texture->bNeedsUpdate) @@ -1012,6 +1020,9 @@ void FCanvasTextureInfo::UpdateAll () Renderer->RenderTextureView(probe->Texture, probe->Viewpoint, probe->FOV); } } + + fixedcolormap = savecolormap; + realfixedcolormap = savecm; } //========================================================================== diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp index 2f955705e..8b1c23b67 100644 --- a/src/resourcefiles/file_7z.cpp +++ b/src/resourcefiles/file_7z.cpp @@ -243,7 +243,7 @@ bool F7ZFile::Open(bool quiet) Archive = NULL; if (!quiet) { - Printf("\n"TEXTCOLOR_RED"%s: ", Filename); + Printf("\n" TEXTCOLOR_RED "%s: ", Filename); if (res == SZ_ERROR_UNSUPPORTED) { Printf("Decoder does not support this archive\n"); diff --git a/src/s_playlist.cpp b/src/s_playlist.cpp index ce82a8182..c7af3b0c5 100644 --- a/src/s_playlist.cpp +++ b/src/s_playlist.cpp @@ -63,7 +63,7 @@ bool FPlayList::ChangeList (const char *path) if ( (file = fopen (path, "rb")) == NULL) { - Printf ("Could not open "TEXTCOLOR_BOLD"%s"TEXTCOLOR_NORMAL": %s\n", path, strerror(errno)); + Printf ("Could not open " TEXTCOLOR_BOLD "%s" TEXTCOLOR_NORMAL ": %s\n", path, strerror(errno)); return false; } diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 35fcc44e2..bdc1a3928 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1683,7 +1683,7 @@ bool S_GetSoundPlayingInfo (const FPolyObj *poly, int sound_id) // //========================================================================== -bool S_IsChannelUsed(AActor *actor, int channel, int *seen) +static bool S_IsChannelUsed(AActor *actor, int channel, int *seen) { if (*seen & (1 << channel)) { diff --git a/src/sc_man.cpp b/src/sc_man.cpp index 514e1ac64..6b275a822 100644 --- a/src/sc_man.cpp +++ b/src/sc_man.cpp @@ -952,7 +952,7 @@ void STACK_ARGS FScanner::ScriptMessage (const char *message, ...) va_end (arglist); } - Printf (TEXTCOLOR_RED"Script error, \"%s\" line %d:\n"TEXTCOLOR_RED"%s\n", ScriptName.GetChars(), + Printf (TEXTCOLOR_RED "Script error, \"%s\" line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(), AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); } diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 46e3898ff..292da5930 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -616,7 +616,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad) const char *str; if((str=getenv("KDE_FULL_SESSION")) && strcmp(str, "true") == 0) { - FString cmd("kdialog --title \""GAMESIG" "); + FString cmd("kdialog --title \"" GAMESIG " "); cmd << GetVersionString() << ": Select an IWAD to use\"" " --menu \"ZDoom found more than one IWAD\n" "Select from the list below to determine which one to use:\""; diff --git a/src/sdl/iwadpicker_cocoa.mm b/src/sdl/iwadpicker_cocoa.mm index 1a1fa8b8c..a0469ac7a 100644 --- a/src/sdl/iwadpicker_cocoa.mm +++ b/src/sdl/iwadpicker_cocoa.mm @@ -156,7 +156,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; cancelled = false; app = [NSApplication sharedApplication]; - id windowTitle = [NSString stringWithUTF8String:GAMESIG " " DOTVERSIONSTR ": Select an IWAD to use"]; + id windowTitle = [NSString stringWithFormat:@GAMESIG " %s: Select an IWAD to use", GetVersionString()]; NSRect frame = NSMakeRect(0, 0, 440, 450); window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]; diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 6dd7a5459..c21ba4054 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -732,8 +732,8 @@ bool FMODSoundRenderer::Init() } if (wrongver != NULL) { - Printf (" "TEXTCOLOR_ORANGE"Error! You are using %s version of FMOD (%x.%02x.%02x).\n" - " "TEXTCOLOR_ORANGE"This program was built for version %x.%02x.%02x\n", + Printf (" " TEXTCOLOR_ORANGE "Error! You are using %s version of FMOD (%x.%02x.%02x).\n" + " " TEXTCOLOR_ORANGE "This program was built for version %x.%02x.%02x\n", wrongver, version >> 16, (version >> 8) & 255, version & 255, FMOD_VERSION >> 16, (FMOD_VERSION >> 8) & 255, FMOD_VERSION & 255); @@ -1261,15 +1261,15 @@ void FMODSoundRenderer::PrintStatus() unsigned int bufferlength; int numbuffers; - Printf ("Loaded FMOD version: "TEXTCOLOR_GREEN"%x.%02x.%02x\n", ActiveFMODVersion >> 16, + Printf ("Loaded FMOD version: " TEXTCOLOR_GREEN "%x.%02x.%02x\n", ActiveFMODVersion >> 16, (ActiveFMODVersion >> 8) & 255, ActiveFMODVersion & 255); if (FMOD_OK == Sys->getOutput(&output)) { - Printf ("Output type: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(OutputNames, output)); + Printf ("Output type: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(OutputNames, output)); } if (FMOD_OK == Sys->getSpeakerMode(&speakermode)) { - Printf ("Speaker mode: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(SpeakerModeNames, speakermode)); + Printf ("Speaker mode: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(SpeakerModeNames, speakermode)); } if (FMOD_OK == Sys->getDriver(&driver)) { @@ -1278,19 +1278,19 @@ void FMODSoundRenderer::PrintStatus() { strcpy(name, "Unknown"); } - Printf ("Driver: "TEXTCOLOR_GREEN"%d"TEXTCOLOR_NORMAL" ("TEXTCOLOR_ORANGE"%s"TEXTCOLOR_NORMAL")\n", driver, name); + Printf ("Driver: " TEXTCOLOR_GREEN "%d" TEXTCOLOR_NORMAL " (" TEXTCOLOR_ORANGE "%s" TEXTCOLOR_NORMAL ")\n", driver, name); DumpDriverCaps(Driver_Caps, Driver_MinFrequency, Driver_MaxFrequency); } if (FMOD_OK == Sys->getSoftwareFormat(&samplerate, &format, &numoutputchannels, NULL, &resampler, NULL)) { - Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: "TEXTCOLOR_GREEN"%d\n", samplerate); - Printf (TEXTCOLOR_LIGHTBLUE "Software mixer format: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(SoundFormatNames, format)); - Printf (TEXTCOLOR_LIGHTBLUE "Software mixer channels: "TEXTCOLOR_GREEN"%d\n", numoutputchannels); - Printf (TEXTCOLOR_LIGHTBLUE "Software mixer resampler: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(ResamplerNames, resampler)); + Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: " TEXTCOLOR_GREEN "%d\n", samplerate); + Printf (TEXTCOLOR_LIGHTBLUE "Software mixer format: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(SoundFormatNames, format)); + Printf (TEXTCOLOR_LIGHTBLUE "Software mixer channels: " TEXTCOLOR_GREEN "%d\n", numoutputchannels); + Printf (TEXTCOLOR_LIGHTBLUE "Software mixer resampler: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(ResamplerNames, resampler)); } if (FMOD_OK == Sys->getDSPBufferSize(&bufferlength, &numbuffers)) { - Printf (TEXTCOLOR_LIGHTBLUE "DSP buffers: "TEXTCOLOR_GREEN"%u samples x %d\n", bufferlength, numbuffers); + Printf (TEXTCOLOR_LIGHTBLUE "DSP buffers: " TEXTCOLOR_GREEN "%u samples x %d\n", bufferlength, numbuffers); } } @@ -1302,8 +1302,8 @@ void FMODSoundRenderer::PrintStatus() void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int maxfrequency) { - Printf (TEXTCOLOR_OLIVE " Min. frequency: "TEXTCOLOR_GREEN"%d\n", minfrequency); - Printf (TEXTCOLOR_OLIVE " Max. frequency: "TEXTCOLOR_GREEN"%d\n", maxfrequency); + Printf (TEXTCOLOR_OLIVE " Min. frequency: " TEXTCOLOR_GREEN "%d\n", minfrequency); + Printf (TEXTCOLOR_OLIVE " Max. frequency: " TEXTCOLOR_GREEN "%d\n", maxfrequency); Printf (" Features:\n"); if (caps == 0) Printf(TEXTCOLOR_OLIVE " None\n"); if (caps & FMOD_CAPS_HARDWARE) Printf(TEXTCOLOR_OLIVE " Hardware mixing\n"); @@ -1318,7 +1318,7 @@ void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int max { Printf("\n"); } - if (caps & FMOD_CAPS_REVERB_LIMITED) Printf("TEXTCOLOR_OLIVE Limited reverb\n"); + if (caps & FMOD_CAPS_REVERB_LIMITED) Printf(TEXTCOLOR_OLIVE " Limited reverb\n"); } //========================================================================== @@ -1386,11 +1386,11 @@ FString FMODSoundRenderer::GatherStats() } #endif - out.Format ("%d channels,"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%% CPU " - "(DSP:"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%% " - "Stream:"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%% " - "Geometry:"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%% " - "Update:"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%%)", + out.Format ("%d channels," TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% CPU " + "(DSP:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% " + "Stream:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% " + "Geometry:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% " + "Update:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%%)", channels, total, dsp, stream, geometry, update); return out; } diff --git a/src/sound/music_fluidsynth_mididevice.cpp b/src/sound/music_fluidsynth_mididevice.cpp index 2e86cb2ee..53a93fe09 100644 --- a/src/sound/music_fluidsynth_mididevice.cpp +++ b/src/sound/music_fluidsynth_mididevice.cpp @@ -620,10 +620,10 @@ FString FluidSynthMIDIDevice::GetStats() fluid_settings_getint(FluidSettings, "synth.polyphony", &maxpoly); CritSec.Leave(); - out.Format("Voices: "TEXTCOLOR_YELLOW"%3d"TEXTCOLOR_NORMAL"/"TEXTCOLOR_ORANGE"%3d"TEXTCOLOR_NORMAL"("TEXTCOLOR_RED"%3d"TEXTCOLOR_NORMAL")" - TEXTCOLOR_YELLOW"%6.2f"TEXTCOLOR_NORMAL"%% CPU " - "Reverb: "TEXTCOLOR_YELLOW"%3s"TEXTCOLOR_NORMAL - " Chorus: "TEXTCOLOR_YELLOW"%3s", + out.Format("Voices: " TEXTCOLOR_YELLOW "%3d" TEXTCOLOR_NORMAL "/" TEXTCOLOR_ORANGE "%3d" TEXTCOLOR_NORMAL "(" TEXTCOLOR_RED "%3d" TEXTCOLOR_NORMAL ")" + TEXTCOLOR_YELLOW "%6.2f" TEXTCOLOR_NORMAL "%% CPU " + "Reverb: " TEXTCOLOR_YELLOW "%3s" TEXTCOLOR_NORMAL + " Chorus: " TEXTCOLOR_YELLOW "%3s", voices, polyphony, maxpoly, load, reverb, chorus); return out; } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index b2c132ea5..6b36a9812 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -70,6 +70,7 @@ #include "m_bbox.h" #include "r_data/r_translate.h" #include "p_trace.h" +#include "gstrings.h" static FRandom pr_camissile ("CustomActorfire"); @@ -2300,6 +2301,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Print) PARAM_FLOAT_OPT (time) { time = 0; } PARAM_NAME_OPT (fontname) { fontname = NAME_None; } + if (text[0] == '$') text = GStrings(&text[1]); if (self->CheckLocalView (consoleplayer) || (self->target != NULL && self->target->CheckLocalView (consoleplayer))) { @@ -2338,6 +2340,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PrintBold) float saved = con_midtime; FFont *font = NULL; + if (text[0] == '$') text = GStrings(&text[1]); if (fontname != NAME_None) { font = V_GetFont(fontname); @@ -2363,12 +2366,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Log) { PARAM_ACTION_PROLOGUE; PARAM_STRING(text); - Printf("%s\n", text.GetChars()); + + if (text[0] == '$') text = GStrings(&text[1]); + Printf("%s\n", text); ACTION_SET_RESULT(false); // Prints should never set the result for inventory state chains! return numret; } -//=========================================================================== +//========================================================================= // // A_LogInt // diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index eff01efdb..b1df39d90 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -2455,6 +2455,15 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, viewheight, F, PlayerPawn) defaults->ViewHeight = z; } +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(player, userange, F, PlayerPawn) +{ + PROP_FIXED_PARM(z, 0); + defaults->UseRange = z; +} + //========================================================================== // //========================================================================== diff --git a/src/version.h b/src/version.h index 1038e401b..8bdd8ca81 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4501 +#define SAVEVER 4502 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/wadsrc/CMakeLists.txt b/wadsrc/CMakeLists.txt index 422052511..83dc8292d 100644 --- a/wadsrc/CMakeLists.txt +++ b/wadsrc/CMakeLists.txt @@ -1,11 +1,3 @@ cmake_minimum_required( VERSION 2.4 ) -get_target_property(ZIPDIR_EXE zipdir LOCATION) - -add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/zdoom.pk3 - COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/zdoom.pk3 ${CMAKE_CURRENT_SOURCE_DIR}/static - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/zdoom.pk3 $ - DEPENDS zipdir ${CMAKE_CURRENT_SOURCE_DIR}/static ) - -add_custom_target( pk3 ALL - DEPENDS ${ZDOOM_OUTPUT_DIR}/zdoom.pk3 ) +add_pk3(zdoom.pk3 ${CMAKE_CURRENT_SOURCE_DIR}/static) diff --git a/wadsrc/static/actors/shared/player.txt b/wadsrc/static/actors/shared/player.txt index 05fb998c3..5457880a7 100644 --- a/wadsrc/static/actors/shared/player.txt +++ b/wadsrc/static/actors/shared/player.txt @@ -24,6 +24,7 @@ Actor PlayerPawn : Actor native Player.GruntSpeed 12 Player.FallingScreamSpeed 35,40 Player.ViewHeight 41 + Player.UseRange 64 Player.ForwardMove 1,1 Player.SideMove 1,1 Player.ColorRange 0,0 diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index a84ba218b..4b75dfaba 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -353,3 +353,26 @@ F481922F4881F74760F3C0437FD5EDD0 // map03 // make the blue key spawn above the 3D floor setthingz 918 296 } + +64B6CE3CB7349B6F6B1A885C449ACB96 // Super Sonic Doom, map31 +{ + // During the end-of-level tally, both PROP_FROZEN and PROP_TOTALLYFROZEN + // are set, but only PROP_TOTALLYFROZEN is cleared, so PROP_FROZEN is + // still set when returning to the origin map. + linkfrozenprops +} + +D62DCA9EC226DE49108D5DD9271F7631 // Cheogsh 2 map04 +{ + // Stuff in megasphere cage is positioned too low + setthingz 1640 528 + setthingz 1641 528 + setthingz 1642 528 + setthingz 1643 528 + setthingz 1644 528 + setthingz 1645 528 + setthingz 1646 528 + setthingz 1647 528 + setthingz 1648 528 + setthingz 1649 528 +} \ No newline at end of file diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 0c8fff5d3..4b5225f54 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -112,6 +112,7 @@ PD_YELLOWCO = "You need a yellow card to activate this object"; PD_BLUESO = "You need a blue skull to activate this object"; PD_REDSO = "You need a red skull to activate this object"; PD_YELLOWSO = "You need a yellow skull to activate this object"; +NEWSAVE = ""; GGSAVED = "game saved."; HUSTR_MSGU = "[Message unsent]"; PICKUP_PISTOL_DROPPED = "Picked up a pistol.";