diff --git a/src/g_statusbar/sbar_mugshot.cpp b/src/g_statusbar/sbar_mugshot.cpp index f1d43af28..493124389 100644 --- a/src/g_statusbar/sbar_mugshot.cpp +++ b/src/g_statusbar/sbar_mugshot.cpp @@ -479,7 +479,7 @@ FGameTexture *FMugShot::GetFace(player_t *player, const char *default_face, int if (CurrentState != NULL) { int skin = player->userinfo.GetSkin(); - const char *skin_face = (stateflags & FMugShot::CUSTOM) ? nullptr : (player->morphTics ? (GetDefaultByType(player->MorphedPlayerClass))->NameVar(NAME_Face).GetChars() : Skins[skin].Face.GetChars()); + const char *skin_face = (stateflags & FMugShot::CUSTOM) ? nullptr : (player->mo->alternative != nullptr ? (GetDefaultByType(player->MorphedPlayerClass))->NameVar(NAME_Face).GetChars() : Skins[skin].Face.GetChars()); return CurrentState->GetCurrentFrameTexture(default_face, skin_face, level, angle); } return NULL; diff --git a/src/namedef_custom.h b/src/namedef_custom.h index f0cb451c6..0727a4a44 100644 --- a/src/namedef_custom.h +++ b/src/namedef_custom.h @@ -145,7 +145,6 @@ xx(Reflection) xx(CustomInventory) xx(Inventory) xx(StateProvider) -xx(ObtainInventory) xx(CallTryPickup) xx(QuestItem25) xx(QuestItem28) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 733239df2..865810cdc 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -1149,7 +1149,7 @@ void FLevelLocals::UnSnapshotLevel(bool hubLoad) // If this isn't the unmorphed original copy of a player, destroy it, because it's extra. for (i = 0; i < MAXPLAYERS; ++i) { - if (PlayerInGame(i) && Players[i]->morphTics && Players[i]->mo->alternative == pawn) + if (PlayerInGame(i) && Players[i]->mo->alternative == pawn) { break; } diff --git a/src/playsim/a_morph.cpp b/src/playsim/a_morph.cpp index 80e6807af..5f6c38b91 100644 --- a/src/playsim/a_morph.cpp +++ b/src/playsim/a_morph.cpp @@ -37,7 +37,7 @@ bool P_MorphActor(AActor *activator, AActor *victim, PClassActor *ptype, PClassA bool P_UnmorphActor(AActor *activator, AActor *morphed, int flags, bool force) { - IFVIRTUALPTR(morphed, AActor, UnMorph) + IFVIRTUALPTR(morphed, AActor, Unmorph) { VMValue params[] = { morphed, activator, flags, force }; int retval; diff --git a/src/playsim/p_enemy.cpp b/src/playsim/p_enemy.cpp index 6111a6019..b5bf36133 100644 --- a/src/playsim/p_enemy.cpp +++ b/src/playsim/p_enemy.cpp @@ -3115,7 +3115,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Pain) PARAM_SELF_PROLOGUE(AActor); // [RH] Vary player pain sounds depending on health (ala Quake2) - if (self->player && self->player->morphTics == 0) + if (self->player && self->alternative == nullptr) { const char *pain_amount; FSoundID sfx_id = NO_SOUND; diff --git a/src/playsim/p_interaction.cpp b/src/playsim/p_interaction.cpp index 00ef947b6..db19107b7 100644 --- a/src/playsim/p_interaction.cpp +++ b/src/playsim/p_interaction.cpp @@ -329,8 +329,10 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf VMValue params[] = { this }; VMCall(func, params, 1, nullptr, 0); - // Always kill the dummy Actor if it didn't unmorph, otherwise checking the morph flags. - if (realMo != nullptr && (!(morphStyle & MORPH_UNDOBYDEATH) || !(morphStyle & MORPH_UNDOBYDEATHSAVES))) + // Kill the dummy Actor if it didn't unmorph, otherwise checking the morph flags. Player pawns need + // to stay, otherwise they won't respawn correctly. + if (realMo != nullptr + && ((alternative != nullptr && player == nullptr) || (alternative == nullptr && !(morphStyle & MORPH_UNDOBYDEATHSAVES)))) { if (wasgibbed) { @@ -460,7 +462,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf ++source->player->spreecount; } - if (source->player->morphTics) + if (source->alternative != nullptr) { // Make a super chicken source->GiveInventoryType (PClass::FindActor(NAME_PowerWeaponLevel2)); } @@ -1331,7 +1333,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da if (damage >= player->health && !telefragDamage && (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch) - && !player->morphTics) + && target->alternative == nullptr) { // Try to use some inventory health P_AutoUseHealth (player, damage - player->health + 1); } @@ -1465,7 +1467,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da // check for special fire damage or ice damage deaths if (mod == NAME_Fire) { - if (player && !player->morphTics) + if (player && target->alternative == nullptr) { // Check for flame death if (!inflictor || ((target->health > -50) && (damage > 25)) || @@ -1799,7 +1801,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPain } if (damage >= player->health && (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch) - && !player->morphTics) + && target->alternative == nullptr) { // Try to use some inventory health P_AutoUseHealth(player, damage - player->health+1); } @@ -1829,7 +1831,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPain else { target->special1 = damage; - if (player && !player->morphTics) + if (player && target->alternative == nullptr) { // Check for flame death if ((player->poisontype == NAME_Fire) && (target->health > -50) && (damage > 25)) { diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index f980c9a8d..c3f4a82d5 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -835,7 +835,7 @@ int P_GetRealMaxHealth(AActor *actor, int max) { max = actor->GetMaxHealth(true); // [MH] First step in predictable generic morph effects - if (player->morphTics) + if (actor->alternative != nullptr) { if (player->MorphStyle & MORPH_FULLHEALTH) { @@ -857,7 +857,7 @@ int P_GetRealMaxHealth(AActor *actor, int max) else { // Bonus health should be added on top of the item's limit. - if (player->morphTics == 0 || (player->MorphStyle & MORPH_ADDSTAMINA)) + if (actor->alternative == nullptr || (player->MorphStyle & MORPH_ADDSTAMINA)) { max += actor->IntVar(NAME_BonusHealth); } @@ -5225,14 +5225,6 @@ void PlayerPointerSubstitution(AActor* oldPlayer, AActor* newPlayer) return; } - // Swap over the inventory. - auto func = dyn_cast(newPlayer->GetClass()->FindSymbol(NAME_ObtainInventory, true)); - if (func) - { - VMValue params[] = { newPlayer, oldPlayer }; - VMCall(func->Variants[0].Implementation, params, 2, nullptr, 0); - } - // Go through player infos. for (int i = 0; i < MAXPLAYERS; ++i) { @@ -5314,11 +5306,10 @@ int MorphPointerSubstitution(AActor* from, AActor* to) // Since the check is good, move the inventory items over. This should always be done when // morphing to emulate Heretic/Hexen's behavior since those stored the inventory in their // player structs. - auto func = dyn_cast(to->GetClass()->FindSymbol(NAME_ObtainInventory, true)); - if (func) + IFVM(Actor, ObtainInventory) { VMValue params[] = { to, from }; - VMCall(func->Variants[0].Implementation, params, 2, nullptr, 0); + VMCall(func, params, 2, nullptr, 0); } // Only change some gameplay-related pointers that we know we can safely swap to whatever diff --git a/src/playsim/p_user.cpp b/src/playsim/p_user.cpp index 49353dcf2..a1888d5c1 100644 --- a/src/playsim/p_user.cpp +++ b/src/playsim/p_user.cpp @@ -693,7 +693,7 @@ bool player_t::Resurrect() P_BringUpWeapon(this); } - if (morphTics) + if (mo->alternative != nullptr) { P_UnmorphActor(mo, mo); } @@ -1172,7 +1172,7 @@ void P_CheckEnvironment(player_t *player) P_PlayerOnSpecialFlat(player, P_GetThingFloorType(player->mo)); } if (player->mo->Vel.Z <= -player->mo->FloatVar(NAME_FallingScreamMinSpeed) && - player->mo->Vel.Z >= -player->mo->FloatVar(NAME_FallingScreamMaxSpeed) && !player->morphTics && + player->mo->Vel.Z >= -player->mo->FloatVar(NAME_FallingScreamMaxSpeed) && player->mo->alternative == nullptr && player->mo->waterlevel == 0) { auto id = S_FindSkinnedSound(player->mo, S_FindSound("*falling")); diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 5326a6184..b35c8cd8e 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -1406,7 +1406,7 @@ class Actor : Thinker native bool grunted; // [RH] only make noise if alive - if (self.health > 0 && self.player.morphTics == 0) + if (self.health > 0 && !Alternative) { grunted = false; // Why should this number vary by gravity? diff --git a/wadsrc/static/zscript/actors/heretic/chicken.zs b/wadsrc/static/zscript/actors/heretic/chicken.zs index 4bc2e20de..a49418ca3 100644 --- a/wadsrc/static/zscript/actors/heretic/chicken.zs +++ b/wadsrc/static/zscript/actors/heretic/chicken.zs @@ -221,7 +221,7 @@ class ChickenPlayer : PlayerPawn pspr.y = WEAPONTOP + player.chickenPeck / 2; } } - if (player.morphTics & 15) + if ((player.MorphTics ? player.MorphTics : Random[ChickenPlayerThink]()) & 15) { return; } diff --git a/wadsrc/static/zscript/actors/hexen/pig.zs b/wadsrc/static/zscript/actors/hexen/pig.zs index 45c601c4e..95e90722e 100644 --- a/wadsrc/static/zscript/actors/hexen/pig.zs +++ b/wadsrc/static/zscript/actors/hexen/pig.zs @@ -145,7 +145,7 @@ class PigPlayer : PlayerPawn override void MorphPlayerThink () { - if (player.morphTics & 15) + if ((player.MorphTics ? player.MorphTics : Random[PigPlayerThink]()) & 15) { return; } diff --git a/wadsrc/static/zscript/actors/inventory/powerups.zs b/wadsrc/static/zscript/actors/inventory/powerups.zs index 381f26af0..da436dcdc 100644 --- a/wadsrc/static/zscript/actors/inventory/powerups.zs +++ b/wadsrc/static/zscript/actors/inventory/powerups.zs @@ -1933,7 +1933,7 @@ class PowerMorph : Powerup EMorphFlags mStyle = MorphedPlayer ? MorphedPlayer.MorphStyle : MorphStyle; - Owner.Unmorph(Owner, 0, mStyle & MRF_UNDOALWAYS); + Owner.Unmorph(Owner, force: mStyle & MRF_UNDOALWAYS); MorphedPlayer = null; } } diff --git a/wadsrc/static/zscript/actors/inventory/weapons.zs b/wadsrc/static/zscript/actors/inventory/weapons.zs index 49e32f3a2..66a7f8964 100644 --- a/wadsrc/static/zscript/actors/inventory/weapons.zs +++ b/wadsrc/static/zscript/actors/inventory/weapons.zs @@ -262,7 +262,7 @@ class Weapon : StateProvider } let psp = player.GetPSprite(PSP_WEAPON); if (!psp) return; - if (player.morphTics || player.cheats & CF_INSTANTWEAPSWITCH) + if (Alternative || player.cheats & CF_INSTANTWEAPSWITCH) { psp.y = WEAPONBOTTOM; } diff --git a/wadsrc/static/zscript/actors/morph.zs b/wadsrc/static/zscript/actors/morph.zs index 6a418714a..21b2767a9 100644 --- a/wadsrc/static/zscript/actors/morph.zs +++ b/wadsrc/static/zscript/actors/morph.zs @@ -94,7 +94,7 @@ extend class Actor virtual bool CheckUnmorph() { - return UnmorphTime <= Level.Time && Unmorph(self); + return UnmorphTime && UnmorphTime <= Level.Time && Unmorph(self, MRF_UNDOBYTIMEOUT); } //--------------------------------------------------------------------------- diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index ec020d2f3..d87fc1706 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -477,7 +477,7 @@ class PlayerPawn : Actor let player = self.player; if (!player) return; if ((player.WeaponState & WF_DISABLESWITCH) || // Weapon changing has been disabled. - player.morphTics != 0) // Morphed classes cannot change weapons. + Alternative) // Morphed classes cannot change weapons. { // ...so throw away any pending weapon requests. player.PendingWeapon = WP_NOCHANGE; } @@ -651,7 +651,7 @@ class PlayerPawn : Actor } } - if (player.morphTics) + if (Alternative) { bob = 0; } @@ -1072,7 +1072,7 @@ class PlayerPawn : Actor virtual bool CanCrouch() const { - return player.morphTics == 0 || bCrouchableMorph; + return !Alternative || bCrouchableMorph; } //---------------------------------------------------------------------------- @@ -1238,7 +1238,7 @@ class PlayerPawn : Actor side *= SideMove2; } - if (!player.morphTics) + if (!Alternative) { double factor = 1.; for(let it = Inv; it != null; it = it.Inv) @@ -1528,13 +1528,13 @@ class PlayerPawn : Actor { let player = self.player; // Morph counter - if (player.morphTics) + if (Alternative) { if (player.chickenPeck) { // Chicken attack counter player.chickenPeck -= 3; } - if (!--player.morphTics) + if (player.MorphTics && !--player.MorphTics) { // Attempt to undo the chicken/pig Unmorph(self, MRF_UNDOBYTIMEOUT); } @@ -1661,7 +1661,7 @@ class PlayerPawn : Actor player.jumpTics = 0; } } - if (player.morphTics && !(player.cheats & CF_PREDICTING)) + if (Alternative && !(player.cheats & CF_PREDICTING)) { MorphPlayerThink (); } @@ -2042,9 +2042,9 @@ class PlayerPawn : Actor Inventory item, next; let p = player; - if (p.morphTics != 0) + if (Alternative) { // Undo morph - Unmorph(self, 0, true); + Unmorph(self, force: true); } // 'self' will be no longer valid from here on in case of an unmorph let me = p.mo; diff --git a/wadsrc/static/zscript/actors/player/player_cheat.zs b/wadsrc/static/zscript/actors/player/player_cheat.zs index c2d2581d9..40693fbce 100644 --- a/wadsrc/static/zscript/actors/player/player_cheat.zs +++ b/wadsrc/static/zscript/actors/player/player_cheat.zs @@ -434,7 +434,7 @@ extend class PlayerPawn int style = MRF_UNDOBYTOMEOFPOWER; if (gameinfo.gametype == GAME_Hexen) style |= MRF_UNDOBYCHAOSDEVICE; - if (player.morphTics) + if (Alternative) { if (Unmorph (self)) { @@ -454,7 +454,7 @@ extend class PlayerPawn virtual void CheatTakeWeaps() { - if (player.morphTics || health <= 0) + if (Alternative || health <= 0) { return; } diff --git a/wadsrc/static/zscript/actors/player/player_morph.zs b/wadsrc/static/zscript/actors/player/player_morph.zs index 6d28306ed..594ddebfc 100644 --- a/wadsrc/static/zscript/actors/player/player_morph.zs +++ b/wadsrc/static/zscript/actors/player/player_morph.zs @@ -106,7 +106,7 @@ extend class PlayerPawn if (!duration) duration = DEFMORPHTICS; - if (player.MorphTics) + if (Alternative) { // Player is already a beast. if (bCanSuperMorph && spawnType == GetClass()