mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
- added Skulltag's custom F1 help screen MAPINFO option.
- Fixed: Resurrecting a player must restore all flags words, not just the first one. - Fixed: APowerWeaponLevel2::EndEffect must check PendingWeapon for WP_NOCHANGE. - added Skulltag's high jump rune as a powerup - Added Skulltag's Drain and Regeneration runes as powerups and used specific player sounds for their sound effects instead of using misc/i_pkup. (If I ever decide to implement runes it will be in a way that can use the regular powerups instead of having to define specific classes for them.) - Added Skulltag's PowerQuadDamage and PowerQuarterDamage as more customizable PowerDamage and PowerProtection. These new powerups allow free customization of the damage modification per damage type by inheriting from these classes and setting specific values. Such derived damage/protection powerups will be considered as separate powers so that for example a QuadDamage and a DoubleDamage item can be stacked which would result in 8x damage. - merged player_t::cheats and player_t::Powers into one variable. SVN r529 (trunk)
This commit is contained in:
parent
15e473f729
commit
d60a5ee1b9
17 changed files with 444 additions and 59 deletions
|
@ -1,4 +1,27 @@
|
|||
May 9, 2007 (Changes by Graf Zahl)
|
||||
- added Skulltag's custom F1 help screen MAPINFO option.
|
||||
|
||||
May 4, 2007 (Changes by Graf Zahl)
|
||||
- Fixed: Resurrecting a player must restore all flags words, not just the first one.
|
||||
- Fixed: APowerWeaponLevel2::EndEffect must check PendingWeapon for WP_NOCHANGE.
|
||||
|
||||
May 3, 2007 (Changes by Graf Zahl)
|
||||
- added Skulltag's high jump rune as a powerup
|
||||
|
||||
May 2, 2007 (Changes by Graf Zahl)
|
||||
- Added Skulltag's Drain and Regeneration runes as powerups and used specific player
|
||||
sounds for their sound effects instead of using misc/i_pkup.
|
||||
(If I ever decide to implement runes it will be in a way that can use the regular
|
||||
powerups instead of having to define specific classes for them.)
|
||||
- Added Skulltag's PowerQuadDamage and PowerQuarterDamage as more customizable
|
||||
PowerDamage and PowerProtection. These new powerups allow free customization of
|
||||
the damage modification per damage type by inheriting from these classes and
|
||||
setting specific values. Such derived damage/protection powerups will be considered
|
||||
as separate powers so that for example a QuadDamage and a DoubleDamage item can be
|
||||
stacked which would result in 8x damage.
|
||||
|
||||
May 1, 2007 (Changes by Graf Zahl)
|
||||
- merged player_t::cheats and player_t::Powers into one variable.
|
||||
- Fixed: player_t::Powers was not saved in a savegame.
|
||||
- Removed all unused PW_* player power flags.
|
||||
- Added Skulltag's TimeFreezer powerup.
|
||||
|
|
|
@ -146,33 +146,34 @@ typedef enum
|
|||
//
|
||||
typedef enum
|
||||
{
|
||||
CF_NOCLIP = 1, // No clipping, walk through barriers.
|
||||
CF_GODMODE = 2, // No damage, no health loss.
|
||||
CF_NOMOMENTUM = 4, // Not really a cheat, just a debug aid.
|
||||
CF_NOTARGET = 8, // [RH] Monsters don't target
|
||||
CF_FLY = 16, // [RH] Flying player
|
||||
CF_CHASECAM = 32, // [RH] Put camera behind player
|
||||
CF_FROZEN = 64, // [RH] Don't let the player move
|
||||
CF_REVERTPLEASE = 128, // [RH] Stick camera in player's head if (s)he moves
|
||||
CF_STEPLEFT = 512, // [RH] Play left footstep sound next time
|
||||
CF_FRIGHTENING = 1024, // [RH] Scare monsters away
|
||||
CF_INSTANTWEAPSWITCH= 2048, // [RH] Switch weapons instantly
|
||||
CF_TOTALLYFROZEN = 4096, // [RH] All players can do is press +use
|
||||
CF_PREDICTING = 8192, // [RH] Player movement is being predicted
|
||||
CF_WEAPONREADY = 16384,// [RH] Weapon is in the ready state, so bob it when walking
|
||||
CF_NOCLIP = 1, // No clipping, walk through barriers.
|
||||
CF_GODMODE = 2, // No damage, no health loss.
|
||||
CF_NOMOMENTUM = 4, // Not really a cheat, just a debug aid.
|
||||
CF_NOTARGET = 8, // [RH] Monsters don't target
|
||||
CF_FLY = 16, // [RH] Flying player
|
||||
CF_CHASECAM = 32, // [RH] Put camera behind player
|
||||
CF_FROZEN = 64, // [RH] Don't let the player move
|
||||
CF_REVERTPLEASE = 128, // [RH] Stick camera in player's head if (s)he moves
|
||||
CF_STEPLEFT = 512, // [RH] Play left footstep sound next time
|
||||
CF_FRIGHTENING = 1024, // [RH] Scare monsters away
|
||||
CF_INSTANTWEAPSWITCH= 2048, // [RH] Switch weapons instantly
|
||||
CF_TOTALLYFROZEN = 4096, // [RH] All players can do is press +use
|
||||
CF_PREDICTING = 8192, // [RH] Player movement is being predicted
|
||||
CF_WEAPONREADY = 16384, // [RH] Weapon is in the ready state, so bob it when walking
|
||||
CF_TIMEFREEZE = 32768, // Player has an active time freezer
|
||||
CF_DRAIN = 65536, // Player owns a drain powerup
|
||||
CF_SPEED = 0x20000, // Player owns a speed artifact
|
||||
CF_REGENERATION = 0x40000, // Player owns a regeneration artifact
|
||||
CF_HIGHJUMP = 0x80000, // more Skulltag flags. Implemetation not guaranteed though. ;)
|
||||
CF_REFLECTION = 0x100000,
|
||||
CF_PROSPERITY = 0x200000,
|
||||
CF_DOUBLEFIRINGSPEED= 0x400000,
|
||||
} cheat_t;
|
||||
|
||||
#define WPIECE1 1
|
||||
#define WPIECE2 2
|
||||
#define WPIECE3 4
|
||||
|
||||
enum
|
||||
{
|
||||
PW_SPEED = 1,
|
||||
PW_TIMEFREEZE = 2,
|
||||
//
|
||||
};
|
||||
|
||||
#define WP_NOCHANGE ((AWeapon*)~0)
|
||||
|
||||
//
|
||||
|
@ -232,7 +233,6 @@ public:
|
|||
AWeapon *PendingWeapon; // WP_NOCHANGE if not changing
|
||||
|
||||
int cheats; // bit flags
|
||||
BITFIELD Powers; // powers
|
||||
short refire; // refired shots are less accurate
|
||||
short inconsistant;
|
||||
int killcount, itemcount, secretcount; // for intermission
|
||||
|
|
|
@ -155,7 +155,8 @@ static level_info_t TheDefaultLevelInfo =
|
|||
unnamed, // level_name
|
||||
"COLORMAP", // fadetable
|
||||
+8, // WallVertLight
|
||||
-8 // WallHorizLight
|
||||
-8, // WallHorizLight
|
||||
"", // [RC] F1
|
||||
};
|
||||
|
||||
static cluster_info_t TheDefaultClusterInfo = { 0 };
|
||||
|
@ -281,7 +282,7 @@ static const char *MapInfoMapLevel[] =
|
|||
"compat_dropoff",
|
||||
"compat_boomscroll",
|
||||
"bordertexture",
|
||||
|
||||
"f1", // [RC] F1 help
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -307,6 +308,7 @@ enum EMIType
|
|||
MITYPE_REDIRECT,
|
||||
MITYPE_SPECIALACTION,
|
||||
MITYPE_COMPATFLAG,
|
||||
MITYPE_F1, // [RC] F1 help
|
||||
};
|
||||
|
||||
struct MapInfoHandler
|
||||
|
@ -414,6 +416,7 @@ MapHandlers[] =
|
|||
{ MITYPE_COMPATFLAG, COMPATF_DROPOFF},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_BOOMSCROLL},
|
||||
{ MITYPE_LUMPNAME, lioffset(bordertexture), 0 },
|
||||
{ MITYPE_F1, lioffset(f1), 0, },
|
||||
};
|
||||
|
||||
static const char *MapInfoClusterLevel[] =
|
||||
|
@ -656,6 +659,10 @@ static void G_DoParseMapInfo (int lump)
|
|||
{
|
||||
strcpy (levelinfo->skypic2, levelinfo->skypic1);
|
||||
}
|
||||
if (levelinfo->f1 != NULL)
|
||||
{
|
||||
levelinfo->f1 = copystring (levelinfo->f1);
|
||||
}
|
||||
SetLevelNum (levelinfo, levelinfo->levelnum); // Wipe out matching levelnums from other maps.
|
||||
if (levelinfo->pname[0] != 0)
|
||||
{
|
||||
|
@ -992,6 +999,18 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
|
|||
ReplaceString ((char **)(info + handler->data1), sc_String);
|
||||
break;
|
||||
|
||||
case MITYPE_F1:
|
||||
SC_MustGetString ();
|
||||
{
|
||||
char *colon = strchr (sc_String, ':');
|
||||
if (colon)
|
||||
{
|
||||
*colon = 0;
|
||||
}
|
||||
ReplaceString ((char **)(info + handler->data1), sc_String);
|
||||
}
|
||||
break;
|
||||
|
||||
case MITYPE_MUSIC:
|
||||
SC_MustGetString ();
|
||||
{
|
||||
|
@ -2256,6 +2275,7 @@ void G_InitLevelLocals ()
|
|||
level.levelnum = info->levelnum;
|
||||
level.music = info->music;
|
||||
level.musicorder = info->musicorder;
|
||||
level.f1 = info->f1; // [RC] And import the f1 name
|
||||
|
||||
strncpy (level.level_name, info->level_name, 63);
|
||||
G_MaybeLookupLevelName (NULL);
|
||||
|
|
|
@ -134,6 +134,7 @@ struct level_info_s
|
|||
char *level_name;
|
||||
char fadetable[9];
|
||||
SBYTE WallVertLight, WallHorizLight;
|
||||
char *f1;
|
||||
// TheDefaultLevelInfo initializes everything above this line.
|
||||
int musicorder;
|
||||
FCompressedMemFile *snapshot;
|
||||
|
@ -231,6 +232,8 @@ struct level_locals_s
|
|||
|
||||
SBYTE WallVertLight; // Light diffs for vert/horiz walls
|
||||
SBYTE WallHorizLight;
|
||||
|
||||
char *f1;
|
||||
};
|
||||
typedef struct level_locals_s level_locals_t;
|
||||
|
||||
|
|
|
@ -159,6 +159,7 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
|||
Owner->UseInventory (best);
|
||||
}
|
||||
}
|
||||
damage = newdamage;
|
||||
}
|
||||
if (Inventory != NULL)
|
||||
{
|
||||
|
@ -477,6 +478,7 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
|||
saved = savedPercent >> (FRACBITS-1);
|
||||
}
|
||||
newdamage -= saved;
|
||||
damage = newdamage;
|
||||
}
|
||||
}
|
||||
if (Inventory != NULL)
|
||||
|
|
|
@ -1117,7 +1117,7 @@ void APowerWeaponLevel2::EndEffect ()
|
|||
{
|
||||
player->ReadyWeapon->EndPowerup ();
|
||||
}
|
||||
if (player->PendingWeapon != NULL &&
|
||||
if (player->PendingWeapon != NULL && player->PendingWeapon != WP_NOCHANGE &&
|
||||
player->PendingWeapon->WeaponFlags & WIF_POWERED_UP &&
|
||||
player->PendingWeapon->SisterWeapon != NULL)
|
||||
{
|
||||
|
@ -1175,7 +1175,7 @@ END_DEFAULTS
|
|||
|
||||
void APowerSpeed::InitEffect ()
|
||||
{
|
||||
Owner->player->Powers |= PW_SPEED;
|
||||
Owner->player->cheats |= CF_SPEED;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -1229,7 +1229,7 @@ void APowerSpeed::EndEffect ()
|
|||
{
|
||||
if (Owner != NULL && Owner->player != NULL)
|
||||
{
|
||||
Owner->player->Powers &= ~PW_SPEED;
|
||||
Owner->player->cheats &= ~CF_SPEED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1382,7 +1382,7 @@ void APowerTimeFreezer::InitEffect( )
|
|||
S_PauseSound( false );
|
||||
|
||||
// Give the player and his teammates the power to move when time is frozen.
|
||||
Owner->player->Powers |= PW_TIMEFREEZE;
|
||||
Owner->player->cheats |= CF_TIMEFREEZE;
|
||||
for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ )
|
||||
{
|
||||
if ( playeringame[ulIdx] &&
|
||||
|
@ -1390,7 +1390,7 @@ void APowerTimeFreezer::InitEffect( )
|
|||
players[ulIdx].mo->IsTeammate( Owner )
|
||||
)
|
||||
{
|
||||
players[ulIdx].Powers |= PW_TIMEFREEZE;
|
||||
players[ulIdx].cheats |= CF_TIMEFREEZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1439,7 +1439,7 @@ void APowerTimeFreezer::EndEffect( )
|
|||
}
|
||||
|
||||
// Take away the time freeze power, and his teammates.
|
||||
Owner->player->Powers &= ~PW_TIMEFREEZE;
|
||||
Owner->player->cheats &= ~CF_TIMEFREEZE;
|
||||
for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ )
|
||||
{
|
||||
if ( playeringame[ulIdx] &&
|
||||
|
@ -1447,8 +1447,221 @@ void APowerTimeFreezer::EndEffect( )
|
|||
players[ulIdx].mo->IsTeammate( Owner )
|
||||
)
|
||||
{
|
||||
players[ulIdx].Powers &= ~PW_TIMEFREEZE;
|
||||
players[ulIdx].cheats &= ~CF_TIMEFREEZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Damage powerup ------------------------------------------------------
|
||||
|
||||
IMPLEMENT_STATELESS_ACTOR( APowerDamage, Any, -1, 0 )
|
||||
PROP_Powerup_EffectTics( 25*TICRATE )
|
||||
END_DEFAULTS
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerDamage :: InitEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerDamage::InitEffect( )
|
||||
{
|
||||
// Use sound channel 5 to avoid interference with other actions.
|
||||
if (Owner != NULL) S_SoundID(Owner, 5, SeeSound, 1.0f, ATTN_SURROUND);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerDamage :: EndEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerDamage::EndEffect( )
|
||||
{
|
||||
// Use sound channel 5 to avoid interference with other actions.
|
||||
if (Owner != NULL) S_SoundID(Owner, 5, DeathSound, 1.0f, ATTN_SURROUND);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerDamage :: AbsorbDamage
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerDamage::ModifyDamage(int damage, FName damageType, int &newdamage, bool passive)
|
||||
{
|
||||
static const fixed_t def = 4*FRACUNIT;
|
||||
if (!passive && damage > 0)
|
||||
{
|
||||
DmgFactors * df = GetClass()->ActorInfo->DamageFactors;
|
||||
if (df != NULL)
|
||||
{
|
||||
const fixed_t * pdf = df->CheckKey(damageType);
|
||||
if (pdf== NULL && damageType != NAME_None) pdf = df->CheckKey(NAME_None);
|
||||
if (pdf == NULL) pdf = &def;
|
||||
|
||||
damage = newdamage = FixedMul(damage, *pdf);
|
||||
if (*pdf > 0 && damage == 0) damage = newdamage = 1; // don't allow zero damage as result of an underflow
|
||||
if (Owner != NULL && *pdf > FRACUNIT) S_SoundID(Owner, 5, ActiveSound, 1.0f, ATTN_SURROUND);
|
||||
}
|
||||
}
|
||||
if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive);
|
||||
}
|
||||
|
||||
// Quarter damage powerup ------------------------------------------------------
|
||||
|
||||
IMPLEMENT_STATELESS_ACTOR( APowerProtection, Any, -1, 0 )
|
||||
PROP_Powerup_EffectTics( 25*TICRATE )
|
||||
END_DEFAULTS
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerProtection :: InitEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerProtection::InitEffect( )
|
||||
{
|
||||
// Use sound channel 5 to avoid interference with other actions.
|
||||
if (Owner != NULL) S_SoundID(Owner, 5, SeeSound, 1.0f, ATTN_SURROUND);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerProtection :: EndEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerProtection::EndEffect( )
|
||||
{
|
||||
// Use sound channel 5 to avoid interference with other actions.
|
||||
if (Owner != NULL) S_SoundID(Owner, 5, DeathSound, 1.0f, ATTN_SURROUND);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerProtection :: AbsorbDamage
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerProtection::ModifyDamage(int damage, FName damageType, int &newdamage, bool passive)
|
||||
{
|
||||
static const fixed_t def = FRACUNIT/4;
|
||||
if (passive && damage > 0)
|
||||
{
|
||||
DmgFactors * df = GetClass()->ActorInfo->DamageFactors;
|
||||
if (df != NULL)
|
||||
{
|
||||
const fixed_t * pdf = df->CheckKey(damageType);
|
||||
if (pdf== NULL && damageType != NAME_None) pdf = df->CheckKey(NAME_None);
|
||||
if (pdf == NULL) pdf = &def;
|
||||
|
||||
damage = newdamage = FixedMul(damage, *pdf);
|
||||
if (Owner != NULL && *pdf < FRACUNIT) S_SoundID(Owner, 5, ActiveSound, 1.0f, ATTN_SURROUND);
|
||||
}
|
||||
}
|
||||
if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive);
|
||||
}
|
||||
|
||||
// Drain rune -------------------------------------------------------
|
||||
|
||||
IMPLEMENT_STATELESS_ACTOR( APowerDrain, Any, -1, 0 )
|
||||
PROP_Powerup_EffectTics( 60*TICRATE )
|
||||
END_DEFAULTS
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ARuneDrain :: InitEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerDrain::InitEffect( )
|
||||
{
|
||||
// Give the player the power to drain life from opponents when he damages them.
|
||||
Owner->player->cheats |= CF_DRAIN;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ARuneDrain :: EndEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerDrain::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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Regeneration rune -------------------------------------------------------
|
||||
|
||||
IMPLEMENT_STATELESS_ACTOR( APowerRegeneration, Any, -1, 0 )
|
||||
PROP_Powerup_EffectTics( 120*TICRATE )
|
||||
END_DEFAULTS
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ARuneRegeneration :: InitEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerRegeneration::InitEffect( )
|
||||
{
|
||||
// Give the player the power to regnerate lost life.
|
||||
Owner->player->cheats |= CF_REGENERATION;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ARuneRegeneration :: EndEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerRegeneration::EndEffect( )
|
||||
{
|
||||
// Nothing to do if there's no owner.
|
||||
if (Owner != NULL && Owner->player != NULL)
|
||||
{
|
||||
// Take away the regeneration power.
|
||||
Owner->player->cheats &= ~CF_REGENERATION;
|
||||
}
|
||||
}
|
||||
|
||||
// High jump rune -------------------------------------------------------
|
||||
|
||||
IMPLEMENT_STATELESS_ACTOR( APowerHighJump, Any, -1, 0 )
|
||||
END_DEFAULTS
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ARuneHighJump :: InitEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerHighJump::InitEffect( )
|
||||
{
|
||||
// Give the player the power to jump much higher.
|
||||
Owner->player->cheats |= CF_HIGHJUMP;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ARuneHighJump :: EndEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerHighJump::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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,49 @@ protected:
|
|||
void EndEffect( );
|
||||
};
|
||||
|
||||
class APowerDamage : public APowerup
|
||||
{
|
||||
DECLARE_STATELESS_ACTOR( APowerDamage, APowerup )
|
||||
protected:
|
||||
void InitEffect ();
|
||||
void EndEffect ();
|
||||
virtual void ModifyDamage (int damage, FName damageType, int &newdamage, bool passive);
|
||||
};
|
||||
|
||||
class APowerProtection : public APowerup
|
||||
{
|
||||
DECLARE_STATELESS_ACTOR( APowerProtection, APowerup )
|
||||
protected:
|
||||
void InitEffect ();
|
||||
void EndEffect ();
|
||||
virtual void ModifyDamage (int damage, FName damageType, int &newdamage, bool passive);
|
||||
};
|
||||
|
||||
class APowerDrain : public APowerup
|
||||
{
|
||||
DECLARE_STATELESS_ACTOR( APowerDrain, APowerup )
|
||||
protected:
|
||||
void InitEffect( );
|
||||
void EndEffect( );
|
||||
};
|
||||
|
||||
class APowerRegeneration : public APowerup
|
||||
{
|
||||
DECLARE_STATELESS_ACTOR( APowerRegeneration, APowerup )
|
||||
protected:
|
||||
void InitEffect( );
|
||||
void EndEffect( );
|
||||
};
|
||||
|
||||
class APowerHighJump : public APowerup
|
||||
{
|
||||
DECLARE_STATELESS_ACTOR( APowerHighJump, APowerup )
|
||||
protected:
|
||||
void InitEffect( );
|
||||
void EndEffect( );
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class player_s;
|
||||
|
|
|
@ -760,6 +760,29 @@ void AInventory::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: ModifyDamage
|
||||
//
|
||||
// Allows inventory items to manipulate the amount of damage
|
||||
// inflicted. Damage is the amount of damage that would be done without manipulation,
|
||||
// and newdamage is the amount that should be done after the item has changed
|
||||
// it.
|
||||
// 'active' means it is called by the inflictor, 'passive' by the target.
|
||||
// It may seem that this is redundant and AbsorbDamage is the same. However,
|
||||
// AbsorbDamage is called only for players and also depends on other settings
|
||||
// which are undesirable for a protection artifact.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void AInventory::ModifyDamage (int damage, FName damageType, int &newdamage, bool passive)
|
||||
{
|
||||
if (Inventory != NULL)
|
||||
{
|
||||
Inventory->ModifyDamage (damage, damageType, newdamage, passive);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: AlterWeaponSprite
|
||||
|
|
|
@ -152,6 +152,7 @@ public:
|
|||
virtual void OwnerDied ();
|
||||
|
||||
virtual void AbsorbDamage (int damage, FName damageType, int &newdamage);
|
||||
virtual void ModifyDamage (int damage, FName damageType, int &newdamage, bool passive);
|
||||
virtual int AlterWeaponSprite (vissprite_t *vis);
|
||||
|
||||
virtual PalEntry GetBlend ();
|
||||
|
|
|
@ -271,6 +271,10 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
player->health = player->mo->health = player->mo->GetDefault()->health;
|
||||
player->viewheight = ((APlayerPawn *)player->mo->GetDefault())->ViewHeight;
|
||||
player->mo->flags = player->mo->GetDefault()->flags;
|
||||
player->mo->flags2 = player->mo->GetDefault()->flags2;
|
||||
player->mo->flags3 = player->mo->GetDefault()->flags3;
|
||||
player->mo->flags4 = player->mo->GetDefault()->flags4;
|
||||
player->mo->flags5 = player->mo->GetDefault()->flags5;
|
||||
player->mo->height = player->mo->GetDefault()->height;
|
||||
player->mo->SetState (player->mo->SpawnState);
|
||||
player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players));
|
||||
|
|
|
@ -1427,6 +1427,13 @@ void M_DrawReadThis ()
|
|||
else
|
||||
{
|
||||
tex = TexMan[gameinfo.info.infoPage[InfoType-1]];
|
||||
// Did the mapper choose a custom help page via MAPINFO?
|
||||
if((level.f1 != NULL) && (strcmp(level.f1, "") != 0)) {
|
||||
if(TexMan.CheckForTexture(level.f1,0,0) == -1)
|
||||
TexMan.AddPatch(level.f1); // Needs to be marked as a patch.
|
||||
tex = TexMan[level.f1];
|
||||
}
|
||||
|
||||
if (InfoType > 1)
|
||||
{
|
||||
prevpic = TexMan[gameinfo.info.infoPage[InfoType-2]];
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "gi.h"
|
||||
#include "templates.h"
|
||||
#include "sbar.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
static FRandom pr_obituary ("Obituary");
|
||||
static FRandom pr_botrespawn ("BotRespawn");
|
||||
|
@ -886,32 +887,50 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
|
|||
}
|
||||
}
|
||||
|
||||
// to be removed and replaced by an actual damage factor
|
||||
// once the actors using it are converted to DECORATE.
|
||||
if (mod == NAME_Fire && target->flags4 & MF4_FIRERESIST)
|
||||
{
|
||||
damage /= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
DmgFactors * df = target->GetClass()->ActorInfo->DamageFactors;
|
||||
if (df != NULL)
|
||||
{
|
||||
fixed_t * pdf = df->CheckKey(mod);
|
||||
if (pdf != NULL)
|
||||
{
|
||||
damage = FixedMul(damage, *pdf);
|
||||
if (damage <= 0) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
damage = inflictor->DoSpecialDamage (target, damage);
|
||||
if (damage == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle active damage modifiers (e.g. PowerDamage)
|
||||
if (inflictor->Inventory != NULL)
|
||||
{
|
||||
int olddam = damage;
|
||||
inflictor->Inventory->ModifyDamage(olddam, mod, damage, false);
|
||||
if (olddam != damage && damage <= 0) return;
|
||||
}
|
||||
}
|
||||
// Handle passive damage modifiers (e.g. PowerProtection)
|
||||
if (target->Inventory != NULL)
|
||||
{
|
||||
int olddam = damage;
|
||||
target->Inventory->ModifyDamage(olddam, mod, damage, true);
|
||||
if (olddam != damage && damage <= 0) return;
|
||||
}
|
||||
|
||||
// to be removed and replaced by an actual damage factor
|
||||
// once the actors using it are converted to DECORATE.
|
||||
if (mod == NAME_Fire && target->flags4 & MF4_FIRERESIST)
|
||||
{
|
||||
damage /= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
DmgFactors * df = target->GetClass()->ActorInfo->DamageFactors;
|
||||
if (df != NULL)
|
||||
{
|
||||
fixed_t * pdf = df->CheckKey(mod);
|
||||
if (pdf != NULL)
|
||||
{
|
||||
damage = FixedMul(damage, *pdf);
|
||||
if (damage <= 0) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
|
||||
|
||||
if (damage == -1)
|
||||
{
|
||||
return;
|
||||
|
@ -1061,6 +1080,21 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
|
|||
//
|
||||
// the damage has been dealt; now deal with the consequences
|
||||
//
|
||||
|
||||
// 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)
|
||||
{
|
||||
if (!target->player || target->player != source->player)
|
||||
{
|
||||
if ( P_GiveBody( source, damage / 2 ))
|
||||
{
|
||||
S_Sound( source, CHAN_ITEM, "*drainhealth", 1, ATTN_NORM );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (target->health <= 0)
|
||||
{ // Death
|
||||
target->special1 = damage;
|
||||
|
|
|
@ -2535,7 +2535,7 @@ void AActor::Tick ()
|
|||
}
|
||||
|
||||
// Apply freeze mode.
|
||||
if (( level.flags & LEVEL_FROZEN ) && ( player == NULL || !( player->Powers & PW_TIMEFREEZE )))
|
||||
if (( level.flags & LEVEL_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE )))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -306,7 +306,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
|
|||
if (thing->player && (useFog || !keepOrientation))
|
||||
{
|
||||
// Freeze player for about .5 sec
|
||||
if (!(thing->player->Powers & PW_SPEED))
|
||||
if (!(thing->player->cheats & CF_SPEED))
|
||||
thing->reactiontime = 18;
|
||||
}
|
||||
if (thing->flags & MF_MISSILE)
|
||||
|
|
|
@ -80,7 +80,7 @@ void P_Ticker (void)
|
|||
// off the music.
|
||||
for (i = 0; i < MAXPLAYERS; i++ )
|
||||
{
|
||||
if (playeringame[i] && players[i].Powers & PW_TIMEFREEZE)
|
||||
if (playeringame[i] && players[i].cheats & CF_TIMEFREEZE)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,6 @@ player_s::player_s()
|
|||
ReadyWeapon(0),
|
||||
PendingWeapon(0),
|
||||
cheats(0),
|
||||
Powers(0),
|
||||
refire(0),
|
||||
inconsistant(0),
|
||||
killcount(0),
|
||||
|
@ -1121,7 +1120,7 @@ void APlayerPawn::TweakSpeeds (int &forward, int &side)
|
|||
side = FixedMul (side, SideMove2);
|
||||
}
|
||||
|
||||
if ((player->Powers & PW_SPEED) && !player->morphTics)
|
||||
if ((player->cheats & CF_SPEED) && !player->morphTics)
|
||||
{ // Adjust for a player with a speed artifact
|
||||
forward = (3*forward)>>1;
|
||||
side = (3*side)>>1;
|
||||
|
@ -2062,7 +2061,12 @@ void P_PlayerThink (player_t *player)
|
|||
}
|
||||
else if (!(dmflags & DF_NO_JUMP) && onground && !player->jumpTics)
|
||||
{
|
||||
player->mo->momz += player->mo->JumpZ * 35 / TICRATE;
|
||||
fixed_t jumpmomz = player->mo->JumpZ * 35 / TICRATE;
|
||||
|
||||
// [BC] If the player has the high jump power, double his jump velocity.
|
||||
if ( player->cheats & CF_HIGHJUMP ) jumpmomz *= 2;
|
||||
|
||||
player->mo->momz += jumpmomz;
|
||||
S_Sound (player->mo, CHAN_BODY, "*jump", 1, ATTN_NORM);
|
||||
player->mo->flags2 &= ~MF2_ONMOBJ;
|
||||
player->jumpTics = 18*TICRATE/35;
|
||||
|
@ -2172,6 +2176,15 @@ void P_PlayerThink (player_t *player)
|
|||
P_PoisonDamage (player, player->poisoner, 1, true);
|
||||
}
|
||||
|
||||
// [BC] Apply regeneration.
|
||||
if (( level.time & 31 ) == 0 && ( player->cheats & CF_REGENERATION ) && ( player->health ))
|
||||
{
|
||||
if ( P_GiveBody( player->mo, 5 ))
|
||||
{
|
||||
S_Sound(player->mo, CHAN_ITEM, "*regenerate", 1, ATTN_NORM );
|
||||
}
|
||||
}
|
||||
|
||||
// Handle air supply
|
||||
if (level.airsupply > 0)
|
||||
{
|
||||
|
@ -2359,8 +2372,7 @@ void player_s::Serialize (FArchive &arc)
|
|||
<< BlendB
|
||||
<< BlendA
|
||||
<< accuracy << stamina
|
||||
<< LogText
|
||||
<< Powers;
|
||||
<< LogText;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
arc << frags[i];
|
||||
|
|
|
@ -1073,7 +1073,7 @@ void R_SetupFrame (AActor *actor)
|
|||
iview->oviewangle = iview->nviewangle;
|
||||
}
|
||||
|
||||
if (player != NULL &&
|
||||
if (player != NULL && gamestate != GS_TITLELEVEL &&
|
||||
((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) &&
|
||||
(camera->RenderStyle != STYLE_None) &&
|
||||
!(camera->renderflags & RF_INVISIBLE) &&
|
||||
|
|
Loading…
Reference in a new issue