From 192104aea2a267e67be13aa3e3685ee4f323b2e4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 24 Nov 2018 07:45:49 +0100 Subject: [PATCH] - scriptified P_MorphPlayer and dependencies. It still needs its counterpart scriptified as well before it can work. --- src/g_shared/a_morph.cpp | 12 -- src/gi.cpp | 1 + src/p_user.cpp | 7 + src/scripting/backend/vmbuilder.cpp | 4 +- wadsrc/static/zscript/base.txt | 1 + wadsrc/static/zscript/shared/morph.txt | 218 ++++++++++++++++++++++++ wadsrc/static/zscript/shared/player.txt | 23 ++- 7 files changed, 250 insertions(+), 16 deletions(-) diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 95b85349c..c97e3111d 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -173,18 +173,6 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassActor *spawntype, in return true; } -DEFINE_ACTION_FUNCTION(_PlayerInfo, MorphPlayer) -{ - PARAM_SELF_STRUCT_PROLOGUE(player_t); - PARAM_POINTER(activator, player_t); - PARAM_CLASS(spawntype, APlayerPawn); - PARAM_INT(duration); - PARAM_INT(style); - PARAM_CLASS(enter_flash, AActor); - PARAM_CLASS(exit_flash, AActor); - ACTION_RETURN_BOOL(P_MorphPlayer(activator, self, spawntype, duration, style, enter_flash, exit_flash)); -} - //---------------------------------------------------------------------------- // // FUNC P_UndoPlayerMorph diff --git a/src/gi.cpp b/src/gi.cpp index 87c8b68cf..38aa76d1f 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -61,6 +61,7 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, statusscreen_single) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, statusscreen_coop) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, statusscreen_dm) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mSliderColor) +DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, telefogheight) const char *GameNames[17] = diff --git a/src/p_user.cpp b/src/p_user.cpp index 48ad0ee67..fef2d51d5 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -293,6 +293,13 @@ CCMD (playerclasses) } } +DEFINE_ACTION_FUNCTION(APlayerPawn, Substitute) +{ + PARAM_SELF_PROLOGUE(APlayerPawn); + PARAM_OBJECT(replace, APlayerPawn); + DObject::StaticPointerSubstitution(self, replace); + return 0; +} // // Movement. diff --git a/src/scripting/backend/vmbuilder.cpp b/src/scripting/backend/vmbuilder.cpp index a141c3f8e..9d910bc63 100644 --- a/src/scripting/backend/vmbuilder.cpp +++ b/src/scripting/backend/vmbuilder.cpp @@ -802,7 +802,6 @@ VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo void FFunctionBuildList::Build() { - int errorcount = 0; int codesize = 0; int datasize = 0; FILE *dump = nullptr; @@ -911,7 +910,8 @@ void FFunctionBuildList::Build() } VMFunction::CreateRegUseInfo(); FScriptPosition::StrictErrors = false; - if (Args->CheckParm("-dumpjit")) DumpJit(); + + if (FScriptPosition::ErrorCounter == 0 && Args->CheckParm("-dumpjit")) DumpJit(); mItems.Clear(); mItems.ShrinkToFit(); FxAlloc.FreeAllBlocks(); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 2576ea9b2..fff6f9ecc 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -366,6 +366,7 @@ struct GameInfoStruct native native double gibfactor; native bool intermissioncounter; native Name mSliderColor; + native double telefogheight; } class Object native diff --git a/wadsrc/static/zscript/shared/morph.txt b/wadsrc/static/zscript/shared/morph.txt index 149cf3cea..a2eed3dc0 100644 --- a/wadsrc/static/zscript/shared/morph.txt +++ b/wadsrc/static/zscript/shared/morph.txt @@ -1,3 +1,221 @@ +extend class PlayerPawn +{ + //=========================================================================== + // + // EndAllPowerupEffects + // + // Calls EndEffect() on every Powerup in the inventory list. + // + //=========================================================================== + + void InitAllPowerupEffects() + { + let item = Inv; + while (item != null) + { + let power = Powerup(item); + if (power != null) + { + power.InitEffect(); + } + item = item.Inv; + } + } + + //=========================================================================== + // + // EndAllPowerupEffects + // + // Calls EndEffect() on every Powerup in the inventory list. + // + //=========================================================================== + + void EndAllPowerupEffects() + { + let item = Inv; + while (item != null) + { + let power = Powerup(item); + if (power != null) + { + power.EndEffect(); + } + item = item.Inv; + } + } + + //=========================================================================== + // + // + // + //=========================================================================== + + virtual void ActivateMorphWeapon () + { + class morphweaponcls = MorphWeapon; + player.PendingWeapon = WP_NOCHANGE; + + if (player.ReadyWeapon != null) + { + player.GetPSprite(PSP_WEAPON).y = WEAPONTOP; + } + + if (morphweaponcls == null || !(morphweaponcls is 'Weapon')) + { // No weapon at all while morphed! + player.ReadyWeapon = null; + } + else + { + player.ReadyWeapon = Weapon(FindInventory (morphweaponcls)); + if (player.ReadyWeapon == null) + { + player.ReadyWeapon = Weapon(GiveInventoryType (morphweaponcls)); + if (player.ReadyWeapon != null) + { + player.ReadyWeapon.GivenAsMorphWeapon = true; // flag is used only by new beastweap semantics in P_UndoPlayerMorph + } + } + if (player.ReadyWeapon != null) + { + player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.GetReadyState()); + } + } + + if (player.ReadyWeapon != null) + { + player.SetPsprite(PSP_FLASH, null); + } + + player.PendingWeapon = WP_NOCHANGE; + } + + //--------------------------------------------------------------------------- + // + // FUNC P_MorphPlayer + // + // Returns true if the player gets turned into a chicken/pig. + // + // TODO: Allow morphed players to receive weapon sets (not just one weapon), + // since they have their own weapon slots now. + // + //--------------------------------------------------------------------------- + + virtual bool MorphPlayer(playerinfo activator, Class spawntype, int duration, int style, Class enter_flash = null, Class exit_flash = null) + { + if (bDontMorph) + { + return false; + } + if (bInvulnerable && (player != activator || !(style & MRF_WHENINVULNERABLE))) + { // Immune when invulnerable unless this is a power we activated + return false; + } + if (player.morphTics) + { // Player is already a beast + if ((GetClass() == spawntype) && bCanSuperMorph + && (player.morphTics < (((duration) ? duration : DEFMORPHTICS) - TICRATE)) + && FindInventory('PowerWeaponLevel2', true) == null) + { // Make a super chicken + GiveInventoryType ('PowerWeaponLevel2'); + } + return false; + } + if (health <= 0) + { // Dead players cannot morph + return false; + } + if (spawntype == null) + { + return false; + } + if (!(spawntype is 'PlayerPawn')) + { + return false; + } + if (spawntype == GetClass()) + { + return false; + } + + let morphed = PlayerPawn(Spawn (spawntype, Pos, NO_REPLACE)); + EndAllPowerupEffects(); + Substitute(morphed); + if ((style & MRF_TRANSFERTRANSLATION) && !morphed.bDontTranslate) + { + morphed.Translation = Translation; + } + if (tid != 0 && (style & MRF_NEWTIDBEHAVIOUR)) + { + morphed.ChangeTid(tid); + ChangeTid(0); + } + morphed.Angle = Angle; + morphed.target = target; + morphed.tracer = tracer; + morphed.alternative = self; + morphed.FriendPlayer = FriendPlayer; + morphed.DesignatedTeam = DesignatedTeam; + morphed.Score = Score; + player.PremorphWeapon = player.ReadyWeapon; + + morphed.special2 = bSolid * 2 + bShootable * 4 + bInvisible * 0x40; // The factors are for savegame compatibility + morphed.player = player; + + if (morphed.ViewHeight > player.viewheight && player.deltaviewheight == 0) + { // If the new view height is higher than the old one, start moving toward it. + player.deltaviewheight = player.GetDeltaViewHeight(); + } + morphed.bShadow |= bShadow; + morphed.bNoGravity |= bNoGravity; + morphed.bFly |= bFly; + morphed.bGhost |= bGhost; + + if (enter_flash == null) enter_flash = 'TeleportFog'; + let eflash = Spawn(enter_flash, Pos + (0, 0, gameinfo.telefogheight), ALLOW_REPLACE); + let p = player; + player = null; + alternative = morphed; + bSolid = false; + bShootable = false; + bUnmorphed = true; + bInvisible = true; + + p.morphTics = (duration) ? duration : DEFMORPHTICS; + + // [MH] Used by SBARINFO to speed up face drawing + p.MorphedPlayerClass = spawntype; + + p.MorphStyle = style; + if (exit_flash == null) exit_flash = 'TeleportFog'; + p.MorphExitFlash = exit_flash; + p.health = morphed.health; + p.mo = morphed; + p.vel = (0, 0); + morphed.ObtainInventory (self); + // Remove all armor + for (Inventory item = morphed.Inv; item != null; ) + { + let next = item.Inv; + if (item is 'Armor') + { + item.DepleteOrDestroy(); + } + item = next; + } + morphed.InitAllPowerupEffects(); + morphed.ActivateMorphWeapon (); + if (p.camera == self) // can this happen? + { + p.camera = morphed; + } + morphed.ScoreIcon = ScoreIcon; // [GRB] + if (eflash) + eflash.target = morphed; + return true; + } + +} + class MorphProjectile : Actor { diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index dce27e106..4d47552b9 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -15,6 +15,7 @@ class PlayerPawn : Actor native const CROUCHSPEED = (1./12); // [RH] # of ticks to complete a turn180 const TURN180_TICKS = ((TICRATE / 4) + 1); + const DEFMORPHTICS = 40 * TICRATE; native int crouchsprite; native int MaxHealth; @@ -1261,6 +1262,7 @@ class PlayerPawn : Actor native player.mo.CheckAirSupply(); } } + //---------------------------------------------------------------------------- // @@ -1278,6 +1280,7 @@ class PlayerPawn : Actor native native void CheckWeaponButtons(); native Weapon BestWeapon(class ammotype); native Weapon PickNewWeapon(class ammotype); + native void Substitute(PlayerPawn replacement); } @@ -1434,7 +1437,7 @@ struct PlayerInfo native play // this is what internally is known as player_t native ClassMorphedPlayerClass; native int MorphStyle; native Class MorphExitFlash; - native Class PremorphWeapon; + native Weapon PremorphWeapon; native int chickenPeck; native int jumpTics; native bool onground; @@ -1467,7 +1470,16 @@ struct PlayerInfo native play // this is what internally is known as player_t native readonly @UserCmd original_cmd; - native bool MorphPlayer(playerinfo p, Class spawntype, int duration, int style, Class enter_flash = null, Class exit_flash = null); + bool MorphPlayer(playerinfo p, Class spawntype, int duration, int style, Class enter_flash = null, Class exit_flash = null) + { + if (mo != null) + { + // The actual implementation is on PlayerPawn where it can be overridden. + return mo.MorphPlayer(p, spawntype, duration, style, enter_flash, exit_flash); + } + return false; + } + native bool UndoPlayerMorph(playerinfo player, int unmorphflag = 0, bool force = false); native bool PoisonPlayer(Actor poisoner, Actor source, int poison); native void PoisonDamage(Actor source, int damage, bool playPainSound); @@ -1538,6 +1550,13 @@ struct PlayerInfo native play // this is what internally is known as player_t return allfrags; } + double GetDeltaViewHeight() + { + return (mo.ViewHeight + crouchviewdelta - viewheight) / 8; + } + + + } struct PlayerClass native