diff --git a/src/d_player.h b/src/d_player.h index b16af3611..2d7d439c5 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -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 diff --git a/src/namedef.h b/src/namedef.h index 5aa7e82db..dd4a4f5e3 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -197,7 +197,9 @@ xx(PowerWeaponLevel2) xx(PowerFlight) xx(PowerSpeed) xx(PowerTorch) +xx(PowerHighJump) xx(PowerReflection) +xx(PowerDrain) xx(Reflection) xx(CustomInventory) xx(Inventory) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 2e2dd5682..33605e4e3 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -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 ); } } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index a908e115e..d14c69aad 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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; diff --git a/src/p_user.cpp b/src/p_user.cpp index 53e27c0f5..5bb0e2127 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -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; diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index e2390cfd1..422853ea6 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -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"; diff --git a/wadsrc/static/zscript/inventory/powerups.txt b/wadsrc/static/zscript/inventory/powerups.txt index 1fc63cfbe..3b01c97b3 100644 --- a/wadsrc/static/zscript/inventory/powerups.txt +++ b/wadsrc/static/zscript/inventory/powerups.txt @@ -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; - } - } }