From cccdfd63360bd76e44076e0036ae5c43d6fbb5b8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 6 Feb 2009 00:16:57 +0000 Subject: [PATCH] - fixed: The compatibility parser applied the last map's settings to all maps in the compatibility list. - Added compatibility settings for a few more levels in some classic WADs. - Added spechit overflow workaround for Strain MAP07. This is highly map specific because the original behavior cannot be restored. - Added a check for Doom's IWAD levels that forces COMPAT_SHORTTEX for them. MD5 cannot be used well here because there's many different IWADs with slightly different levels. This is only done for Doom format levels to ensure that custom IWADs for ZDoom are not affected. - fixed: level.flags2 was not reset at level start. - Fixed: Morph powerups can change the actor picking up the item so AInventory::CallTryPickup must be able to return the new actor. - Fixed: ACS's GiveInventory may not assume that a PlayerPawn is still attached to the player data after an item has been given. - Added a missing NULL pointer check to DBaseStatusBar::Blendview. SVN r1405 (trunk) --- docs/rh-log.txt | 19 ++++++++++++++- src/compatibility.cpp | 42 ++++++++++++++++++++++++++------- src/doomdef.h | 1 + src/g_level.cpp | 1 + src/g_shared/a_pickups.cpp | 9 ++++--- src/g_shared/a_pickups.h | 2 +- src/g_shared/shared_sbar.cpp | 2 +- src/m_bbox.h | 2 ++ src/p_acs.cpp | 2 +- src/p_setup.cpp | 10 ++++++++ src/p_user.cpp | 13 ++++++++-- wadsrc/static/compatibility.txt | 30 +++++++++++++++++++++++ 12 files changed, 116 insertions(+), 17 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index f4a9c12128..1f8051527d 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,9 +1,26 @@ +February 5, 2009 (Changes by Graf Zahl) +- fixed: The compatibility parser applied the last map's settings to all + maps in the compatibility list. +- Added compatibility settings for a few more levels in some classic WADs. +- Added spechit overflow workaround for Strain MAP07. This is highly map + specific because the original behavior cannot be restored. +- Added a check for Doom's IWAD levels that forces COMPAT_SHORTTEX for them. + MD5 cannot be used well here because there's many different IWADs with + slightly different levels. This is only done for Doom format levels to + ensure that custom IWADs for ZDoom are not affected. +- fixed: level.flags2 was not reset at level start. +- Fixed: Morph powerups can change the actor picking up the item so + AInventory::CallTryPickup must be able to return the new actor. +- Fixed: ACS's GiveInventory may not assume that a PlayerPawn is still + attached to the player data after an item has been given. +- Added a missing NULL pointer check to DBaseStatusBar::Blendview. + February 4, 2009 - Added a compatibility lump because I think it's a shame that Void doesn't work properly on new ZDooms after all the collaboration I had with Cyb on that map. (Works with other maps, too.) -February 5, 2009 (Changes by Graf Zahl) +February 4, 2009 (Changes by Graf Zahl) - Made improvements so that the FOptionalMapinfoData class is easier to use. February 3, 2009 diff --git a/src/compatibility.cpp b/src/compatibility.cpp index a2cf321f81..68e60b88c7 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -45,6 +45,8 @@ #include "doomdef.h" #include "doomstat.h" #include "c_dispatch.h" +#include "gi.h" +#include "g_level.h" // MACROS ------------------------------------------------------------------ @@ -75,6 +77,7 @@ static FCompatOption Options[] = { { "setslopeoverflow", 0, BCOMPATF_SETSLOPEOVERFLOW }, { "resetplayerspeed", 0, BCOMPATF_RESETPLAYERSPEED }, + { "spechitoverflow", 0, BCOMPATF_SPECHITOVERFLOW }, // list copied from g_mapinfo.cpp { "shorttex", COMPATF_SHORTTEX, 0 }, @@ -169,6 +172,7 @@ void ParseCompatibility() { BCompatMap[md5array[j]] = flags; } + md5array.Clear(); } } @@ -183,20 +187,42 @@ void CheckCompatibility(MapData *map) FMD5Holder md5; FCompatValues *flags; - map->GetChecksum(md5.Bytes); - flags = BCompatMap.CheckKey(md5); - if (flags != NULL) + // When playing Doom IWAD levels force COMPAT_SHORTTEX. + if (Wads.GetLumpFile(map->lumpnum) == 1 && gameinfo.gametype == GAME_Doom && !(level.flags & LEVEL_HEXENFORMAT)) { - ii_compatflags = flags->CompatFlags; - ib_compatflags = flags->BCompatFlags; + ii_compatflags = COMPATF_SHORTTEX; + ib_compatflags = 0; } else { - ii_compatflags = 0; - ib_compatflags = 0; + map->GetChecksum(md5.Bytes); + + flags = BCompatMap.CheckKey(md5); + + if (developer) + { + Printf("MD5 = "); + for (size_t j = 0; j < sizeof(md5.Bytes); ++j) + { + Printf("%02X", md5.Bytes[j]); + } + if (flags != NULL) Printf(", cflags = %08x, bflags = %08x\n", flags->CompatFlags, flags->BCompatFlags); + else Printf("\n"); + } + + if (flags != NULL) + { + ii_compatflags = flags->CompatFlags; + ib_compatflags = flags->BCompatFlags; + } + else + { + ii_compatflags = 0; + ib_compatflags = 0; + } } // Reset i_compatflags - compatflags = compatflags; + compatflags.Callback(); } //========================================================================== diff --git a/src/doomdef.h b/src/doomdef.h index 4346a6d566..718724cc1b 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -288,6 +288,7 @@ enum { BCOMPATF_SETSLOPEOVERFLOW = 1 << 0, // SetSlope things can overflow BCOMPATF_RESETPLAYERSPEED = 1 << 1, // Set player speed to 1.0 when changing maps + BCOMPATF_SPECHITOVERFLOW = 1 << 2, // Emulate spechit overflow (e.g. Strain MAP07) }; // phares 3/20/98: diff --git a/src/g_level.cpp b/src/g_level.cpp index 825ec621c1..a2859ad75e 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1216,6 +1216,7 @@ void G_InitLevelLocals () level.aircontrol = (fixed_t)(sv_aircontrol * 65536.f); level.teamdamage = teamdamage; level.flags = 0; + level.flags2 = 0; info = FindLevelInfo (level.mapname); diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index e466d1cd09..a9689f4af1 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -876,9 +876,9 @@ void AInventory::Touch (AActor *toucher) toucher = toucher->player->mo; } - // This is the only situation when a pickup flash should ever play. - if (!CallTryPickup (toucher)) return; + if (!CallTryPickup (toucher, &toucher)) return; + // This is the only situation when a pickup flash should ever play. if (PickupFlash != NULL && !ShouldStay()) { Spawn(PickupFlash, x, y, z, ALLOW_REPLACE); @@ -1258,10 +1258,13 @@ bool AInventory::TryPickup (AActor *&toucher) // //=========================================================================== -bool AInventory::CallTryPickup (AActor *toucher) +bool AInventory::CallTryPickup (AActor *toucher, AActor **toucher_return) { bool res = TryPickup(toucher); + // Morph items can change the toucher so we need an option to return this info. + if (toucher_return != NULL) *toucher_return = toucher; + if (!res && (ItemFlags & IF_ALWAYSPICKUP) && !ShouldStay()) { res = true; diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index d5d9465fb9..fc56e30473 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -117,7 +117,7 @@ public: virtual bool ShouldRespawn (); virtual bool ShouldStay (); virtual void Hide (); - bool CallTryPickup (AActor *toucher); + bool CallTryPickup (AActor *toucher, AActor **toucher_return = NULL); virtual void DoPickupSpecial (AActor *toucher); virtual bool SpecialDropAction (AActor *dropper); virtual bool DrawPowerup (int x, int y); diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 644e250853..ac1d316867 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1502,7 +1502,7 @@ void DBaseStatusBar::BlendView (float blend[4]) if (screen->Accel2D || (CPlayer->camera != NULL && menuactive == MENU_Off && ConsoleState == c_up)) { - player_t *player = (CPlayer->camera->player != NULL) ? CPlayer->camera->player : CPlayer; + player_t *player = (CPlayer->camera != NULL && CPlayer->camera->player != NULL) ? CPlayer->camera->player : CPlayer; AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend); } diff --git a/src/m_bbox.h b/src/m_bbox.h index bfc9bd7d75..7c72216883 100644 --- a/src/m_bbox.h +++ b/src/m_bbox.h @@ -65,6 +65,8 @@ public: int BoxOnLineSide (const line_t *ld) const; + void Set(int index, fixed_t value) {m_Box[index] = value;} + protected: fixed_t m_Box[4]; }; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 2c192e91e2..612190a391 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -451,7 +451,7 @@ static void DoGiveInv (AActor *actor, const PClass *info, int amount) } // If the item was a weapon, don't bring it up automatically // unless the player was not already using a weapon. - if (savedPendingWeap != NULL && hadweap) + if (savedPendingWeap != NULL && hadweap && actor->player != NULL) { actor->player->PendingWeapon = savedPendingWeap; } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index aeef9bbb87..5465fec1c4 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3423,6 +3423,16 @@ void P_SetupLevel (char *lumpname, int position) P_LoadThings (map); else P_LoadThings2 (map); // [RH] Load Hexen-style things + + if (ib_compatflags & BCOMPATF_SPECHITOVERFLOW) + { + // restoring the original behavior doesn't work so we have to patch the levels in other ways. + // Fortunately the only known level depending on this bug is Strain's MAP07 and that's easy to fix. + if (numlines == 1022) + { + lines[1021].flags &= ~ML_BLOCKING; + } + } } else { diff --git a/src/p_user.cpp b/src/p_user.cpp index d1ef70fc91..8ff455b790 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -978,6 +978,8 @@ void APlayerPawn::ThrowPoisonBag () void APlayerPawn::GiveDefaultInventory () { + if (player == NULL) return; + // [GRB] Give inventory specified in DECORATE player->health = GetDefault ()->health; @@ -1033,13 +1035,20 @@ void APlayerPawn::GiveDefaultInventory () static_cast(item)->AmmoGive1 = static_cast(item)->AmmoGive2 = 0; } - if (!item->CallTryPickup(this)) + AActor *check; + if (!item->CallTryPickup(this, &check)) { + if (check != this) + { + // Player was morphed. This is illegal at game start. + // This problem is only detectable when it's too late to do something about it... + I_Error("Cannot give morph items when starting a game"); + } item->Destroy (); item = NULL; } } - if (item != NULL && item->IsKindOf (RUNTIME_CLASS (AWeapon)) && + if (item != NULL && item->IsKindOf (RUNTIME_CLASS (AWeapon)) && static_cast(item)->CheckAmmo(AWeapon::EitherFire, false)) { player->ReadyWeapon = player->PendingWeapon = static_cast (item); diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index f1afb6cbd9..0601f7370a 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -29,4 +29,34 @@ A80E7EE40E0D0C76A6FBD242BE29FE27 // map15 // What's really sad is that I got a separate bug report for this map // years ago, but nobody made mention of this problem back then. trace + useblocking +} + +// mostly cosmetic (except AV MAP07 and MM2 MAP25) +0EECBF37B328C9CAAF20DED4949A4157 // Sudtic e2m6 +4ACE0644883BDA0CBA254FA02C9ACF83 // Teutic e3m4 +9F2BE080A33F775294BD78822456924E // Nukemine e1m4 +CD31793D3A4B00231B124C0C23649644 // Strain map02 +19094AEB53D12EFC8E0568424F659F11 // Strain map31 +60733BDD1AA3F4B2262ADC79B2E1B5AB // Memento Mori map29 +F84AB4557464A383E93F37CD3A82AC48 // MM2 map03 +1497894956B3C8EBE8A240B7FDD99C6A // MM2 map25 +941E4CB56EE4184E0B1ED43486AB0BBF // AV map07 +{ + shorttex +} + +2FE901F659A16E58D7BCD7C30021C238 // AV map15 +{ + trace +} + +9D50EBE17CEC78938C7A668DB0768611 // Strain map07: Make the exit accessible +{ + spechitoverflow +} + +96368EB950E33AF62EA6423434E3CEF7 // Hacx map17: There's some switches behind shootable covers in this level +{ + useblocking }