- added some flexibility to some Skulltag powerups.

- handle these powerups by actual item checks instead of cheat flags. (The same should also be done for the Frightener and Buddha but those are a bit more complex because they are also real cheats.)
This commit is contained in:
Christoph Oelckers 2017-02-26 16:23:22 +01:00
parent c7668952d9
commit e6b31dde27
7 changed files with 58 additions and 110 deletions

View file

@ -209,13 +209,7 @@ typedef enum
CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use
CF_PREDICTING = 1 << 13, // [RH] Player movement is being predicted
CF_INTERPVIEW = 1 << 14, // [RH] view was changed outside of input, so interpolate one frame
CF_DRAIN = 1 << 16, // Player owns a drain powerup
CF_HIGHJUMP = 1 << 18, // more Skulltag flags. Implementation not guaranteed though. ;)
CF_REFLECTION = 1 << 19,
CF_PROSPERITY = 1 << 20,
CF_DOUBLEFIRINGSPEED= 1 << 21, // Player owns a double firing speed artifact
CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths.
CF_INFINITEAMMO = 1 << 23, // Player owns an infinite ammo artifact
CF_BUDDHA2 = 1 << 24, // [MC] Absolute buddha. No voodoo can kill it either.
CF_GODMODE2 = 1 << 25, // [MC] Absolute godmode. No voodoo can kill it either.
CF_BUDDHA = 1 << 27, // [SP] Buddha mode - take damage, but don't die

View file

@ -197,7 +197,9 @@ xx(PowerWeaponLevel2)
xx(PowerFlight)
xx(PowerSpeed)
xx(PowerTorch)
xx(PowerHighJump)
xx(PowerReflection)
xx(PowerDrain)
xx(Reflection)
xx(CustomInventory)
xx(Inventory)

View file

@ -1164,18 +1164,28 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
}
AInventory *reflect;
//[RC] Backported from the Zandronum source.. Mostly.
if( target->player &&
damage > 0 &&
source &&
(reflect = target->FindInventory(NAME_PowerReflection)) &&
mod != NAME_Reflection)
mod != NAME_Reflection &&
target != source)
{
if ( target != source )
int reflectdamage = 0;
for (auto p = target->player->mo->Inventory; p != nullptr; p = p->Inventory)
{
// This picks the reflection item with the maximum efficiency for the given damage type.
if (p->IsKindOf(NAME_PowerReflection))
{
int mydamage = p->ApplyDamageFactor(mod, damage);
if (mydamage > reflectdamage) reflectdamage = mydamage;
}
}
if (reflectdamage > 0)
{
// use the reflect item's damage factors to get the final value here.
int reflectdamage = reflect->ApplyDamageFactor(mod, damage);
P_DamageMobj(source, nullptr, target, reflectdamage, NAME_Reflection );
// Reset means of death flag.
@ -1439,13 +1449,24 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
// If the damaging player has the power of drain, give the player 50% of the damage
// done in health.
if ( source && source->player && source->player->cheats & CF_DRAIN && !(target->flags5 & MF5_DONTDRAIN))
if ( source && source->player && !(target->flags5 & MF5_DONTDRAIN))
{
if (!target->player || target->player != source->player)
{
if ( P_GiveBody( source, damage / 2 ))
double draindamage = 0;
for (auto p = source->player->mo->Inventory; p != nullptr; p = p->Inventory)
{
S_Sound( source, CHAN_ITEM, "*drainhealth", 1, ATTN_NORM );
// This picks the item with the maximum efficiency.
if (p->IsKindOf(NAME_PowerDrain))
{
double mydamage = p->FloatVar(NAME_Strength);
if (mydamage > draindamage) draindamage = mydamage;
}
}
if ( P_GiveBody( source, int(draindamage * damage)))
{
S_Sound(source, CHAN_ITEM, "*drainhealth", 1, ATTN_NORM );
}
}
}

View file

@ -902,8 +902,7 @@ bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate
// Do not take ammo if the "no take infinite/take as ammo depletion" flag is set
// and infinite ammo is on
if (notakeinfinite &&
((dmflags & DF_INFINITE_AMMO) || (player && player->cheats & CF_INFINITEAMMO)) &&
item->IsKindOf(NAME_Ammo))
((dmflags & DF_INFINITE_AMMO) || (player && FindInventory(NAME_PowerInfiniteAmmo))) && item->IsKindOf(NAME_Ammo))
{
// Nothing to do here, except maybe res = false;? Would it make sense?
result = false;

View file

@ -2689,9 +2689,19 @@ void P_PlayerThink (player_t *player)
else if (level.IsJumpingAllowed() && player->onground && player->jumpTics == 0)
{
double jumpvelz = player->mo->JumpZ * 35 / TICRATE;
double jumpfac = 0;
// [BC] If the player has the high jump power, double his jump velocity.
if ( player->cheats & CF_HIGHJUMP ) jumpvelz *= 2;
// (actually, pick the best factors from all active items.)
for (auto p = player->mo->Inventory; p != nullptr; p = p->Inventory)
{
if (p->IsKindOf(NAME_PowerHighJump))
{
double f = p->FloatVar(NAME_Strength);
if (f > jumpfac) jumpfac = f;
}
}
if (jumpfac > 0) jumpvelz *= jumpfac;
player->mo->Vel.Z += jumpvelz;
player->mo->flags2 &= ~MF2_ONMOBJ;

View file

@ -1088,17 +1088,21 @@ enum EPlayerCheats
CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use
CF_PREDICTING = 1 << 13, // [RH] Player movement is being predicted
CF_INTERPVIEW = 1 << 14, // [RH] view was changed outside of input, so interpolate one frame
CF_DRAIN = 1 << 16, // Player owns a drain powerup
CF_HIGHJUMP = 1 << 18, // more Skulltag flags. Implementation not guaranteed though. ;)
CF_REFLECTION = 1 << 19,
CF_PROSPERITY = 1 << 20,
CF_DOUBLEFIRINGSPEED= 1 << 21, // Player owns a double firing speed artifact
CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths.
CF_INFINITEAMMO = 1 << 23, // Player owns an infinite ammo artifact
CF_BUDDHA2 = 1 << 24, // [MC] Absolute buddha. No voodoo can kill it either.
CF_GODMODE2 = 1 << 25, // [MC] Absolute godmode. No voodoo can kill it either.
CF_BUDDHA = 1 << 27, // [SP] Buddha mode - take damage, but don't die
CF_NOCLIP2 = 1 << 30, // [RH] More Quake-like noclip
// These flags no longer exist, but keep the names for some stray mod that might have used them.
CF_DRAIN = 0,
CF_HIGHJUMP = 0,
CF_REFLECTION = 0,
CF_PROSPERITY = 0,
CF_DOUBLEFIRINGSPEED= 0,
CF_INFINITEAMMO = 0,
};
const TEXTCOLOR_BRICK = "\034A";

View file

@ -1783,32 +1783,9 @@ class PowerDrain : Powerup
{
Default
{
Powerup.Strength 0.5;
Powerup.Duration -60;
}
override void InitEffect()
{
Super.InitEffect();
if (Owner!= null && Owner.player != null)
{
// Give the player the power to drain life from opponents when he damages them.
Owner.player.cheats |= CF_DRAIN;
}
}
override void EndEffect()
{
Super.EndEffect();
// Nothing to do if there's no owner.
if (Owner!= null && Owner.player != null)
{
// Take away the drain power.
Owner.player.cheats &= ~CF_DRAIN;
}
}
}
//===========================================================================
@ -1846,27 +1823,9 @@ class PowerRegeneration : Powerup
class PowerHighJump : Powerup
{
override void InitEffect()
Default
{
Super.InitEffect();
if (Owner!= null && Owner.player != null)
{
// Give the player the power to jump much higher.
Owner.player.cheats |= CF_HIGHJUMP;
}
}
override void EndEffect()
{
Super.EndEffect();
// Nothing to do if there's no owner.
if (Owner!= null && Owner.player != null)
{
// Take away the high jump power.
Owner.player.cheats &= ~CF_HIGHJUMP;
}
Powerup.Strength 2;
}
}
@ -1878,27 +1837,9 @@ class PowerHighJump : Powerup
class PowerDoubleFiringSpeed : Powerup
{
override void InitEffect()
Default
{
Super.InitEffect();
if (Owner!= null && Owner.player != null)
{
// Give the player the power to shoot twice as fast.
Owner.player.cheats |= CF_DOUBLEFIRINGSPEED;
}
}
override void EndEffect()
{
Super.EndEffect();
// Nothing to do if there's no owner.
if (Owner!= null && Owner.player != null)
{
// Take away the shooting twice as fast power.
Owner.player.cheats &= ~CF_DOUBLEFIRINGSPEED;
}
Powerup.Duration -40;
}
}
@ -1914,29 +1855,6 @@ class PowerInfiniteAmmo : Powerup
{
Powerup.Duration -30;
}
override void InitEffect()
{
Super.InitEffect();
if (Owner!= null && Owner.player != null)
{
// Give the player infinite ammo
Owner.player.cheats |= CF_INFINITEAMMO;
}
}
override void EndEffect()
{
Super.EndEffect();
// Nothing to do if there's no owner.
if (Owner!= null && Owner.player != null)
{
// Take away the limitless ammo
Owner.player.cheats &= ~CF_INFINITEAMMO;
}
}
}