diff --git a/src/d_net.cpp b/src/d_net.cpp index dbe07ccf5..0137d911a 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -612,6 +612,11 @@ void PlayerIsGone (int netnode, int netconsole) P_DisconnectEffect (players[netconsole].mo); players[netconsole].mo->player = NULL; players[netconsole].mo->Destroy (); + if (!(players[netconsole].mo->ObjectFlags & OF_EuthanizeMe)) + { // We just destroyed a morphed player, so now the original player + // has taken their place. Destroy that one too. + players[netconsole].mo->Destroy(); + } players[netconsole].mo = NULL; players[netconsole].camera = NULL; } diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index c0dc797fe..0d65bfe44 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1843,24 +1843,26 @@ void APowerMorph::EndEffect( ) } // Unmorph if possible - int savedMorphTics = Player->morphTics; - P_UndoPlayerMorph (Player, Player); - - // Abort if unmorph failed; in that case, - // set the usual retry timer and return. - if (Player->morphTics) + if (!bNoCallUndoMorph) { - // Transfer retry timeout - // to the powerup's timer. - EffectTics = Player->morphTics; - // Reload negative morph tics; - // use actual value; it may - // be in use for animation. - Player->morphTics = savedMorphTics; - // Try again some time later - return; - } + int savedMorphTics = Player->morphTics; + P_UndoPlayerMorph (Player, Player); + // Abort if unmorph failed; in that case, + // set the usual retry timer and return. + if (Player != NULL && Player->morphTics) + { + // Transfer retry timeout + // to the powerup's timer. + EffectTics = Player->morphTics; + // Reload negative morph tics; + // use actual value; it may + // be in use for animation. + Player->morphTics = savedMorphTics; + // Try again some time later + return; + } + } // Unmorph suceeded Player = NULL; } diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 1d775b02b..9987877b0 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -247,6 +247,7 @@ class APowerMorph : public APowerup DECLARE_CLASS( APowerMorph, APowerup ) public: void Serialize (FArchive &arc); + void SetNoCallUndoMorph() { bNoCallUndoMorph = true; } FNameNoInit PlayerClass, MorphFlash, UnMorphFlash; int MorphStyle; @@ -256,6 +257,7 @@ protected: void EndEffect (); // Variables player_t *Player; + bool bNoCallUndoMorph; // Because P_UndoPlayerMorph() can call EndEffect recursively }; #endif //__A_ARTIFACTS_H__ diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 2cd057f3a..ea7d15395 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -202,6 +202,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, next = item->Inventory; if (item->IsKindOf(RUNTIME_CLASS(APowerMorph))) { + static_cast(item)->SetNoCallUndoMorph(); item->Destroy(); } } diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index a1400f04c..2813932db 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -558,6 +558,10 @@ bool AWeapon::DepleteAmmo (bool altFire, bool checkEnough, int ammouse) void AWeapon::PostMorphWeapon () { + if (Owner == NULL) + { + return; + } Owner->player->PendingWeapon = WP_NOCHANGE; Owner->player->ReadyWeapon = this; Owner->player->psprites[ps_weapon].sy = WEAPONBOTTOM;