diff --git a/src/g_game.cpp b/src/g_game.cpp index 34b98c6073..8555db2c49 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1230,7 +1230,7 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, bool resetinventory if (p->morphTics) { // Undo morph - P_UndoPlayerMorph (p, p, true); + P_UndoPlayerMorph (p, p, 0, true); } // Clears the entire inventory and gives back the defaults for starting a game diff --git a/src/g_heretic/a_hereticartifacts.cpp b/src/g_heretic/a_hereticartifacts.cpp index d9c08ec1a4..1b7a799660 100644 --- a/src/g_heretic/a_hereticartifacts.cpp +++ b/src/g_heretic/a_hereticartifacts.cpp @@ -24,7 +24,7 @@ bool AArtiTomeOfPower::Use (bool pickup) { if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYTOMEOFPOWER)) { // Attempt to undo chicken - if (!P_UndoPlayerMorph (Owner->player, Owner->player)) + if (!P_UndoPlayerMorph (Owner->player, Owner->player, MORPH_UNDOBYTOMEOFPOWER)) { // Failed if (!(Owner->player->MorphStyle & MORPH_FAILNOTELEFRAG)) { diff --git a/src/g_raven/a_artitele.cpp b/src/g_raven/a_artitele.cpp index 11350338ed..9828f95817 100644 --- a/src/g_raven/a_artitele.cpp +++ b/src/g_raven/a_artitele.cpp @@ -45,7 +45,8 @@ bool AArtiTeleport::Use (bool pickup) bool canlaugh = true; if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE)) { // Teleporting away will undo any morph effects (pig) - if (!P_UndoPlayerMorph (Owner->player, Owner->player) && (Owner->player->MorphStyle & MORPH_FAILNOLAUGH)) + if (!P_UndoPlayerMorph (Owner->player, Owner->player, MORPH_UNDOBYCHAOSDEVICE) + && (Owner->player->MorphStyle & MORPH_FAILNOLAUGH)) { canlaugh = false; } diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 9ebec54ca4..f12c36aef0 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -173,7 +173,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, i // //---------------------------------------------------------------------------- -bool P_UndoPlayerMorph (player_t *activator, player_t *player, bool force) +bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, bool force) { AWeapon *beastweap; APlayerPawn *mo; @@ -192,10 +192,12 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, bool force) return false; } - if ((pmo->flags2 & MF2_INVULNERABLE) // If the player is invulnerable - && ((player != activator) // and either did not decide to unmorph, - || (!((player->MorphStyle & MORPH_WHENINVULNERABLE) // or the morph style does not allow it - && (player->MorphStyle != MORPH_OLDEFFECTS))))) // (but standard morph styles always allow it), + bool DeliberateUnmorphIsOkay = !!(player->MorphStyle & unmorphflag); + + if ((pmo->flags2 & MF2_INVULNERABLE) // If the player is invulnerable + && ((player != activator) // and either did not decide to unmorph, + || (!((player->MorphStyle & MORPH_WHENINVULNERABLE) // or the morph style does not allow it + || (DeliberateUnmorphIsOkay))))) // (but standard morph styles always allow it), { // Then the player is immune to the unmorph. return false; } diff --git a/src/g_shared/a_morph.h b/src/g_shared/a_morph.h index 7ae83aed45..1ddbf863d5 100644 --- a/src/g_shared/a_morph.h +++ b/src/g_shared/a_morph.h @@ -17,7 +17,7 @@ enum MORPH_UNDOBYCHAOSDEVICE = 0x00000008, // Player unmorphs upon activating a Chaos Device MORPH_FAILNOTELEFRAG = 0x00000010, // Player stays morphed if unmorph by Tome of Power fails MORPH_FAILNOLAUGH = 0x00000020, // Player doesn't laugh if unmorph by Chaos Device fails - MORPH_WHENINVULNERABLE = 0x00000040, // Player can morph (or scripted unmorph) when invulnerable but ONLY if doing it to themselves + MORPH_WHENINVULNERABLE = 0x00000040, // Player can morph when invulnerable but ONLY if doing it to themselves MORPH_LOSEACTUALWEAPON = 0x00000080, // Player loses specified morph weapon only (not "whichever they have when unmorphing") MORPH_NEWTIDBEHAVIOUR = 0x00000100, // Actor TID is by default transferred from the old actor to the new actor MORPH_UNDOBYDEATH = 0x00000200, // Actor unmorphs when killed and (unless MORPH_UNDOBYDEATHSAVES) stays dead @@ -32,7 +32,7 @@ class AMorphedMonster; bool P_MorphPlayer (player_t *activator, player_t *player, const PClass *morphclass, int duration = 0, int style = 0, const PClass *enter_flash = NULL, const PClass *exit_flash = NULL); -bool P_UndoPlayerMorph (player_t *activator, player_t *player, bool force = false); +bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag = 0, bool force = false); bool P_MorphMonster (AActor *actor, const PClass *morphclass, int duration = 0, int style = 0, const PClass *enter_flash = NULL, const PClass *exit_flash = NULL); bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force = false);