From 15f30886cdc838ae06e60343adb275f1764cd2ef Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Jan 2017 20:06:20 +0100 Subject: [PATCH 1/2] - scriptified the TimeFreezer powerup. --- src/g_inventory/a_artifacts.cpp | 128 ---------------------- src/g_level.cpp | 1 + src/s_sound.cpp | 17 +++ wadsrc/static/zscript/base.txt | 3 + wadsrc/static/zscript/shared/powerups.txt | 123 ++++++++++++++++++++- 5 files changed, 143 insertions(+), 129 deletions(-) diff --git a/src/g_inventory/a_artifacts.cpp b/src/g_inventory/a_artifacts.cpp index 335565efd..4bd1b67d5 100644 --- a/src/g_inventory/a_artifacts.cpp +++ b/src/g_inventory/a_artifacts.cpp @@ -1481,134 +1481,6 @@ void APowerBuddha::EndEffect () Owner->player->cheats &= ~CF_BUDDHA; } -// Time freezer powerup ----------------------------------------------------- - -IMPLEMENT_CLASS( APowerTimeFreezer, false, false) - -//=========================================================================== -// -// APowerTimeFreezer :: InitEffect -// -//=========================================================================== - -void APowerTimeFreezer::InitEffect() -{ - int freezemask; - - Super::InitEffect(); - - if (Owner == NULL || Owner->player == NULL) - return; - - // When this powerup is in effect, pause the music. - S_PauseSound(false, false); - - // Give the player and his teammates the power to move when time is frozen. - freezemask = 1 << (Owner->player - players); - Owner->player->timefreezer |= freezemask; - for (int i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && - players[i].mo != NULL && - players[i].mo->IsTeammate(Owner) - ) - { - players[i].timefreezer |= freezemask; - } - } - - // [RH] The effect ends one tic after the counter hits zero, so make - // sure we start at an odd count. - EffectTics += !(EffectTics & 1); - if ((EffectTics & 1) == 0) - { - EffectTics++; - } - // Make sure the effect starts and ends on an even tic. - if ((level.time & 1) == 0) - { - level.flags2 |= LEVEL2_FROZEN; - } - else - { - // Compensate for skipped tic, but beware of overflow. - if(EffectTics < INT_MAX) - EffectTics++; - } -} - -//=========================================================================== -// -// APowerTimeFreezer :: DoEffect -// -//=========================================================================== - -void APowerTimeFreezer::DoEffect() -{ - Super::DoEffect(); - // [RH] Do not change LEVEL_FROZEN on odd tics, or the Revenant's tracer - // will get thrown off. - // [ED850] Don't change it if the player is predicted either. - if (level.time & 1 || (Owner != NULL && Owner->player != NULL && Owner->player->cheats & CF_PREDICTING)) - { - return; - } - // [RH] The "blinking" can't check against EffectTics exactly or it will - // never happen, because InitEffect ensures that EffectTics will always - // be odd when level.time is even. - if ( EffectTics > 4*32 - || (( EffectTics > 3*32 && EffectTics <= 4*32 ) && ((EffectTics + 1) & 15) != 0 ) - || (( EffectTics > 2*32 && EffectTics <= 3*32 ) && ((EffectTics + 1) & 7) != 0 ) - || (( EffectTics > 32 && EffectTics <= 2*32 ) && ((EffectTics + 1) & 3) != 0 ) - || (( EffectTics > 0 && EffectTics <= 1*32 ) && ((EffectTics + 1) & 1) != 0 )) - level.flags2 |= LEVEL2_FROZEN; - else - level.flags2 &= ~LEVEL2_FROZEN; -} - -//=========================================================================== -// -// APowerTimeFreezer :: EndEffect -// -//=========================================================================== - -void APowerTimeFreezer::EndEffect() -{ - int i; - - Super::EndEffect(); - - // If there is an owner, remove the timefreeze flag corresponding to - // her from all players. - if (Owner != NULL && Owner->player != NULL) - { - int freezemask = ~(1 << (Owner->player - players)); - for (i = 0; i < MAXPLAYERS; ++i) - { - players[i].timefreezer &= freezemask; - } - } - - // Are there any players who still have timefreezer bits set? - for (i = 0; i < MAXPLAYERS; ++i) - { - if (playeringame[i] && players[i].timefreezer != 0) - { - break; - } - } - - if (i == MAXPLAYERS) - { - // No, so allow other actors to move about freely once again. - level.flags2 &= ~LEVEL2_FROZEN; - - // Also, turn the music back on. - S_ResumeSound(false); - } -} - - // Morph powerup ------------------------------------------------------ IMPLEMENT_CLASS(APowerMorph, false, true) diff --git a/src/g_level.cpp b/src/g_level.cpp index e6d1618bf..6865607d5 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1888,6 +1888,7 @@ DEFINE_FIELD_BIT(FLevelLocals, flags2, monsterfallingdamage, LEVEL2_MONSTERFALLI DEFINE_FIELD_BIT(FLevelLocals, flags2, checkswitchrange, LEVEL2_CHECKSWITCHRANGE) DEFINE_FIELD_BIT(FLevelLocals, flags2, polygrind, LEVEL2_POLYGRIND) DEFINE_FIELD_BIT(FLevelLocals, flags2, nomonsters, LEVEL2_NOMONSTERS) +DEFINE_FIELD_BIT(FLevelLocals, flags2, frozen, LEVEL2_FROZEN) //========================================================================== // diff --git a/src/s_sound.cpp b/src/s_sound.cpp index be1b572f1..a37182e20 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1852,6 +1852,15 @@ void S_PauseSound (bool notmusic, bool notsfx) } } +DEFINE_ACTION_FUNCTION(DObject, S_PauseSound) +{ + PARAM_PROLOGUE; + PARAM_BOOL(notmusic); + PARAM_BOOL(notsfx); + S_PauseSound(notmusic, notsfx); + return 0; +} + //========================================================================== // // S_ResumeSound @@ -1873,6 +1882,14 @@ void S_ResumeSound (bool notsfx) } } +DEFINE_ACTION_FUNCTION(DObject, S_ResumeSound) +{ + PARAM_PROLOGUE; + PARAM_BOOL(notsfx); + S_ResumeSound(notsfx); + return 0; +} + //========================================================================== // // S_SetSoundPaused diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index e609610e6..38fa79b76 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -9,6 +9,8 @@ class Object native native static vector3, int G_PickPlayerStart(int pnum, int flags = 0); native static int GameType(); native static void S_Sound (Sound sound_id, int channel, float volume = 1, float attenuation = ATTN_NORM); + native static void S_PauseSound (bool notmusic, bool notsfx); + native static void S_ResumeSound (bool notsfx); native static bool S_ChangeMusic(String music_name, int order = 0, bool looping = true, bool force = false); native static void C_MidPrint(string fontname, string textlabel, bool bold = false); // always uses the stringtable. native static uint BAM(double angle); @@ -138,6 +140,7 @@ struct LevelLocals native native bool checkswitchrange; native bool polygrind; native bool nomonsters; + native bool frozen; // level_info_t *info cannot be done yet. } diff --git a/wadsrc/static/zscript/shared/powerups.txt b/wadsrc/static/zscript/shared/powerups.txt index 1ef333f60..e653cb275 100644 --- a/wadsrc/static/zscript/shared/powerups.txt +++ b/wadsrc/static/zscript/shared/powerups.txt @@ -228,12 +228,133 @@ class PowerScanner : Powerup } } -class PowerTimeFreezer : Powerup native +//=========================================================================== +// +// TimeFreezer +// +//=========================================================================== + +class PowerTimeFreezer : Powerup { Default { Powerup.Duration -12; } + + //=========================================================================== + // + // InitEffect + // + //=========================================================================== + + override void InitEffect() + { + int freezemask; + + Super.InitEffect(); + + if (Owner == null || Owner.player == null) + return; + + // When this powerup is in effect, pause the music. + S_PauseSound(false, false); + + // Give the player and his teammates the power to move when time is frozen. + freezemask = 1 << Owner.PlayerNumber(); + Owner.player.timefreezer |= freezemask; + for (int i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && + players[i].mo != null && + players[i].mo.IsTeammate(Owner) + ) + { + players[i].timefreezer |= freezemask; + } + } + + // [RH] The effect ends one tic after the counter hits zero, so make + // sure we start at an odd count. + EffectTics += !(EffectTics & 1); + if ((EffectTics & 1) == 0) + { + EffectTics++; + } + // Make sure the effect starts and ends on an even tic. + if ((level.time & 1) == 0) + { + level.frozen = true;; + } + else + { + // Compensate for skipped tic, but beware of overflow. + if(EffectTics < 0x7fffffff) + EffectTics++; + } + } + + //=========================================================================== + // + // APowerTimeFreezer :: DoEffect + // + //=========================================================================== + + override void DoEffect() + { + Super.DoEffect(); + // [RH] Do not change LEVEL_FROZEN on odd tics, or the Revenant's tracer + // will get thrown off. + // [ED850] Don't change it if the player is predicted either. + if (level.time & 1 || (Owner != null && Owner.player != null && Owner.player.cheats & CF_PREDICTING)) + { + return; + } + // [RH] The "blinking" can't check against EffectTics exactly or it will + // never happen, because InitEffect ensures that EffectTics will always + // be odd when level.time is even. + level.frozen = ( EffectTics > 4*32 + || (( EffectTics > 3*32 && EffectTics <= 4*32 ) && ((EffectTics + 1) & 15) != 0 ) + || (( EffectTics > 2*32 && EffectTics <= 3*32 ) && ((EffectTics + 1) & 7) != 0 ) + || (( EffectTics > 32 && EffectTics <= 2*32 ) && ((EffectTics + 1) & 3) != 0 ) + || (( EffectTics > 0 && EffectTics <= 1*32 ) && ((EffectTics + 1) & 1) != 0 )); + } + + //=========================================================================== + // + // APowerTimeFreezer :: EndEffect + // + //=========================================================================== + + override void EndEffect() + { + Super.EndEffect(); + + // If there is an owner, remove the timefreeze flag corresponding to + // her from all players. + if (Owner != null && Owner.player != null) + { + int freezemask = ~(1 << Owner.PlayerNumber()); + for (int i = 0; i < MAXPLAYERS; ++i) + { + players[i].timefreezer &= freezemask; + } + } + + // Are there any players who still have timefreezer bits set? + for (int i = 0; i < MAXPLAYERS; ++i) + { + if (playeringame[i] && players[i].timefreezer != 0) + { + return; + } + } + + // No, so allow other actors to move about freely once again. + level.frozen = false; + + // Also, turn the music back on. + S_ResumeSound(false); + } } //=========================================================================== From b132782c4986b26cebd3c2ac9b9adcf0586622dc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Jan 2017 21:03:05 +0100 Subject: [PATCH 2/2] - scriptified PowerBuddha and PowerFrightener. --- src/d_dehacked.cpp | 22 +++---- src/g_inventory/a_artifacts.cpp | 76 ----------------------- src/g_inventory/a_artifacts.h | 30 --------- wadsrc/static/zscript/shared/powerups.txt | 58 ++++++++++++++++- 4 files changed, 66 insertions(+), 120 deletions(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index ed2310d45..82f811301 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1890,16 +1890,16 @@ static int PatchMisc (int dummy) "Minotaur", NULL }; - static const PClass * const *types[] = + static const char *const types[] = { - &RUNTIME_CLASS_CASTLESS(APowerInvulnerable), - &RUNTIME_CLASS_CASTLESS(APowerStrength), - &RUNTIME_CLASS_CASTLESS(APowerInvisibility), - &RUNTIME_CLASS_CASTLESS(APowerIronFeet), - &RUNTIME_CLASS_CASTLESS(APowerLightAmp), - &RUNTIME_CLASS_CASTLESS(APowerWeaponLevel2), - &RUNTIME_CLASS_CASTLESS(APowerSpeed), - &RUNTIME_CLASS_CASTLESS(APowerMinotaur) + "PowerInvulnerable", + "PowerStrength", + "PowerInvisibility", + "PowerIronFeet", + "PowerLightAmp", + "PowerWeaponLevel2", + "PowerSpeed", + "PowerMinotaur" }; int i; @@ -1925,7 +1925,7 @@ static int PatchMisc (int dummy) } else if (a > 0) { - static_cast(GetDefaultByType (*types[i]))->BlendColor = PalEntry( + static_cast(GetDefaultByName (types[i]))->BlendColor = PalEntry( BYTE(clamp(a,0.f,1.f)*255.f), clamp(r,0,255), clamp(g,0,255), @@ -1933,7 +1933,7 @@ static int PatchMisc (int dummy) } else { - static_cast(GetDefaultByType (*types[i]))->BlendColor = 0; + static_cast(GetDefaultByName (types[i]))->BlendColor = 0; } } } diff --git a/src/g_inventory/a_artifacts.cpp b/src/g_inventory/a_artifacts.cpp index 4bd1b67d5..9b67e2dc9 100644 --- a/src/g_inventory/a_artifacts.cpp +++ b/src/g_inventory/a_artifacts.cpp @@ -1290,10 +1290,6 @@ void APowerSpeed::DoEffect () } } -// Minotaur (aka Dark Servant) powerup --------------------------------------- - -IMPLEMENT_CLASS(APowerMinotaur, false, false) - // Targeter powerup --------------------------------------------------------- IMPLEMENT_CLASS(APowerTargeter, false, false) @@ -1409,78 +1405,6 @@ void APowerTargeter::PositionAccuracy () } } -// Frightener Powerup -------------------------------- - -IMPLEMENT_CLASS(APowerFrightener, false, false) - -//=========================================================================== -// -// APowerFrightener :: InitEffect -// -//=========================================================================== - -void APowerFrightener::InitEffect () -{ - Super::InitEffect(); - - if (Owner== NULL || Owner->player == NULL) - return; - - Owner->player->cheats |= CF_FRIGHTENING; -} - -//=========================================================================== -// -// APowerFrightener :: EndEffect -// -//=========================================================================== - -void APowerFrightener::EndEffect () -{ - Super::EndEffect(); - - if (Owner== NULL || Owner->player == NULL) - return; - - Owner->player->cheats &= ~CF_FRIGHTENING; -} - -// Buddha Powerup -------------------------------- - -IMPLEMENT_CLASS(APowerBuddha, false, false) - -//=========================================================================== -// -// APowerBuddha :: InitEffect -// -//=========================================================================== - -void APowerBuddha::InitEffect () -{ - Super::InitEffect(); - - if (Owner== NULL || Owner->player == NULL) - return; - - Owner->player->cheats |= CF_BUDDHA; -} - -//=========================================================================== -// -// APowerBuddha :: EndEffect -// -//=========================================================================== - -void APowerBuddha::EndEffect () -{ - Super::EndEffect(); - - if (Owner== NULL || Owner->player == NULL) - return; - - Owner->player->cheats &= ~CF_BUDDHA; -} - // Morph powerup ------------------------------------------------------ IMPLEMENT_CLASS(APowerMorph, false, true) diff --git a/src/g_inventory/a_artifacts.h b/src/g_inventory/a_artifacts.h index 746d22589..f8eec5554 100644 --- a/src/g_inventory/a_artifacts.h +++ b/src/g_inventory/a_artifacts.h @@ -160,11 +160,6 @@ public: #define PSF_NOTRAIL 1 -class APowerMinotaur : public APowerup -{ - DECLARE_CLASS (APowerMinotaur, APowerup) -}; - class APowerTargeter : public APowerup { DECLARE_CLASS (APowerTargeter, APowerup) @@ -178,31 +173,6 @@ protected: virtual bool HandlePickup(AInventory *item) override; }; -class APowerFrightener : public APowerup -{ - DECLARE_CLASS (APowerFrightener, APowerup) -protected: - virtual void InitEffect () override; - virtual void EndEffect () override; -}; - -class APowerBuddha : public APowerup -{ - DECLARE_CLASS (APowerBuddha, APowerup) -protected: - virtual void InitEffect () override; - virtual void EndEffect () override; -}; - -class APowerTimeFreezer : public APowerup -{ - DECLARE_CLASS( APowerTimeFreezer, APowerup ) -protected: - virtual void InitEffect() override; - virtual void DoEffect() override; - virtual void EndEffect() override; -}; - class APowerMorph : public APowerup { DECLARE_CLASS( APowerMorph, APowerup ) diff --git a/wadsrc/static/zscript/shared/powerups.txt b/wadsrc/static/zscript/shared/powerups.txt index e653cb275..549c3eece 100644 --- a/wadsrc/static/zscript/shared/powerups.txt +++ b/wadsrc/static/zscript/shared/powerups.txt @@ -169,7 +169,7 @@ class PlayerSpeedTrail : Actor } } -class PowerMinotaur : Powerup native +class PowerMinotaur : Powerup { Default { @@ -197,20 +197,72 @@ class PowerTargeter : Powerup native } } -class PowerFrightener : Powerup native +//=========================================================================== +// +// Frightener +// +//=========================================================================== + +class PowerFrightener : Powerup { Default { Powerup.Duration -60; } + + override void InitEffect () + { + Super.InitEffect(); + + if (Owner== null || Owner.player == null) + return; + + Owner.player.cheats |= CF_FRIGHTENING; + } + + override void EndEffect () + { + Super.EndEffect(); + + if (Owner== null || Owner.player == null) + return; + + Owner.player.cheats &= ~CF_FRIGHTENING; + } } -class PowerBuddha : Powerup native +//=========================================================================== +// +// Buddha +// +//=========================================================================== + +class PowerBuddha : Powerup { Default { Powerup.Duration -60; } + + override void InitEffect () + { + Super.InitEffect(); + + if (Owner== null || Owner.player == null) + return; + + Owner.player.cheats |= CF_BUDDHA; + } + + override void EndEffect () + { + Super.EndEffect(); + + if (Owner== null || Owner.player == null) + return; + + Owner.player.cheats &= ~CF_BUDDHA; + } } //===========================================================================