This commit is contained in:
Rachael Alexanderson 2017-01-03 21:31:55 -05:00
commit 13972eed2b
7 changed files with 209 additions and 249 deletions

View file

@ -1890,16 +1890,16 @@ static int PatchMisc (int dummy)
"Minotaur", "Minotaur",
NULL NULL
}; };
static const PClass * const *types[] = static const char *const types[] =
{ {
&RUNTIME_CLASS_CASTLESS(APowerInvulnerable), "PowerInvulnerable",
&RUNTIME_CLASS_CASTLESS(APowerStrength), "PowerStrength",
&RUNTIME_CLASS_CASTLESS(APowerInvisibility), "PowerInvisibility",
&RUNTIME_CLASS_CASTLESS(APowerIronFeet), "PowerIronFeet",
&RUNTIME_CLASS_CASTLESS(APowerLightAmp), "PowerLightAmp",
&RUNTIME_CLASS_CASTLESS(APowerWeaponLevel2), "PowerWeaponLevel2",
&RUNTIME_CLASS_CASTLESS(APowerSpeed), "PowerSpeed",
&RUNTIME_CLASS_CASTLESS(APowerMinotaur) "PowerMinotaur"
}; };
int i; int i;
@ -1925,7 +1925,7 @@ static int PatchMisc (int dummy)
} }
else if (a > 0) else if (a > 0)
{ {
static_cast<APowerup *>(GetDefaultByType (*types[i]))->BlendColor = PalEntry( static_cast<APowerup *>(GetDefaultByName (types[i]))->BlendColor = PalEntry(
BYTE(clamp(a,0.f,1.f)*255.f), BYTE(clamp(a,0.f,1.f)*255.f),
clamp(r,0,255), clamp(r,0,255),
clamp(g,0,255), clamp(g,0,255),
@ -1933,7 +1933,7 @@ static int PatchMisc (int dummy)
} }
else else
{ {
static_cast<APowerup *>(GetDefaultByType (*types[i]))->BlendColor = 0; static_cast<APowerup *>(GetDefaultByName (types[i]))->BlendColor = 0;
} }
} }
} }

View file

@ -1291,10 +1291,6 @@ void APowerSpeed::DoEffect ()
} }
} }
// Minotaur (aka Dark Servant) powerup ---------------------------------------
IMPLEMENT_CLASS(APowerMinotaur, false, false)
// Targeter powerup --------------------------------------------------------- // Targeter powerup ---------------------------------------------------------
IMPLEMENT_CLASS(APowerTargeter, false, false) IMPLEMENT_CLASS(APowerTargeter, false, false)
@ -1410,206 +1406,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;
}
// 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 ------------------------------------------------------ // Morph powerup ------------------------------------------------------
IMPLEMENT_CLASS(APowerMorph, false, true) IMPLEMENT_CLASS(APowerMorph, false, true)

View file

@ -160,11 +160,6 @@ public:
#define PSF_NOTRAIL 1 #define PSF_NOTRAIL 1
class APowerMinotaur : public APowerup
{
DECLARE_CLASS (APowerMinotaur, APowerup)
};
class APowerTargeter : public APowerup class APowerTargeter : public APowerup
{ {
DECLARE_CLASS (APowerTargeter, APowerup) DECLARE_CLASS (APowerTargeter, APowerup)
@ -178,31 +173,6 @@ protected:
virtual bool HandlePickup(AInventory *item) override; 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 class APowerMorph : public APowerup
{ {
DECLARE_CLASS( APowerMorph, APowerup ) DECLARE_CLASS( APowerMorph, APowerup )

View file

@ -1889,6 +1889,7 @@ DEFINE_FIELD_BIT(FLevelLocals, flags2, monsterfallingdamage, LEVEL2_MONSTERFALLI
DEFINE_FIELD_BIT(FLevelLocals, flags2, checkswitchrange, LEVEL2_CHECKSWITCHRANGE) DEFINE_FIELD_BIT(FLevelLocals, flags2, checkswitchrange, LEVEL2_CHECKSWITCHRANGE)
DEFINE_FIELD_BIT(FLevelLocals, flags2, polygrind, LEVEL2_POLYGRIND) DEFINE_FIELD_BIT(FLevelLocals, flags2, polygrind, LEVEL2_POLYGRIND)
DEFINE_FIELD_BIT(FLevelLocals, flags2, nomonsters, LEVEL2_NOMONSTERS) DEFINE_FIELD_BIT(FLevelLocals, flags2, nomonsters, LEVEL2_NOMONSTERS)
DEFINE_FIELD_BIT(FLevelLocals, flags2, frozen, LEVEL2_FROZEN)
//========================================================================== //==========================================================================
// //

View file

@ -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 // 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 // S_SetSoundPaused

View file

@ -9,6 +9,8 @@ class Object native
native static vector3, int G_PickPlayerStart(int pnum, int flags = 0); native static vector3, int G_PickPlayerStart(int pnum, int flags = 0);
native static int GameType(); 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_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 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 void C_MidPrint(string fontname, string textlabel, bool bold = false); // always uses the stringtable.
native static uint BAM(double angle); native static uint BAM(double angle);
@ -138,6 +140,7 @@ struct LevelLocals native
native bool checkswitchrange; native bool checkswitchrange;
native bool polygrind; native bool polygrind;
native bool nomonsters; native bool nomonsters;
native bool frozen;
// level_info_t *info cannot be done yet. // level_info_t *info cannot be done yet.
} }

View file

@ -169,7 +169,7 @@ class PlayerSpeedTrail : Actor
} }
} }
class PowerMinotaur : Powerup native class PowerMinotaur : Powerup
{ {
Default Default
{ {
@ -197,20 +197,72 @@ class PowerTargeter : Powerup native
} }
} }
class PowerFrightener : Powerup native //===========================================================================
//
// Frightener
//
//===========================================================================
class PowerFrightener : Powerup
{ {
Default Default
{ {
Powerup.Duration -60; 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 Default
{ {
Powerup.Duration -60; 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;
}
} }
//=========================================================================== //===========================================================================
@ -228,12 +280,133 @@ class PowerScanner : Powerup
} }
} }
class PowerTimeFreezer : Powerup native //===========================================================================
//
// TimeFreezer
//
//===========================================================================
class PowerTimeFreezer : Powerup
{ {
Default Default
{ {
Powerup.Duration -12; 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);
}
} }
//=========================================================================== //===========================================================================