- Fixed: A_CountdownArg and A_Die must ensure a certain kill.

- Changed bounce flags into a property and added real bouncing sound properties.
  Compatibility modes to preserve use of the SeeSound are present and the old
  flags map to these.


SVN r1599 (trunk)
This commit is contained in:
Christoph Oelckers 2009-05-23 08:30:36 +00:00
parent 466b6e4535
commit e61b4b3c76
21 changed files with 241 additions and 146 deletions

View file

@ -1,9 +1,17 @@
May 22, 2009 May 22, 2009 (Changes by Graf Zahl)
- Fixed: A_CountdownArg and A_Die must ensure a certain kill.
May 22, 2009
- Fixed: When using Win32 mouse, windowed mode, alt-tabbing away and then - Fixed: When using Win32 mouse, windowed mode, alt-tabbing away and then
clicking on the window's title bar moved it practically off the screen. clicking on the window's title bar moved it practically off the screen.
- Beginnings of i_input.cpp rewrite: Win32 and DirectInput mouse handling has - Beginnings of i_input.cpp rewrite: Win32 and DirectInput mouse handling has
been moved into classes. been moved into classes.
May 21, 2009 (Changes by Graf Zahl)
- Changed bounce flags into a property and added real bouncing sound properties.
Compatibility modes to preserve use of the SeeSound are present and the old
flags map to these.
May 20, 2009 (Changes by Graf Zahl) May 20, 2009 (Changes by Graf Zahl)
- Fixed: The SBARINFO parser compared an FString in the GAMEINFO with a NULL - Fixed: The SBARINFO parser compared an FString in the GAMEINFO with a NULL
pointer and tried to load a lump with an empty name as statusbar script pointer and tried to load a lump with an empty name as statusbar script

View file

@ -155,7 +155,7 @@ enum
MF2_DONTREFLECT = 0x00000001, // this projectile cannot be reflected MF2_DONTREFLECT = 0x00000001, // this projectile cannot be reflected
MF2_WINDTHRUST = 0x00000002, // gets pushed around by the wind specials MF2_WINDTHRUST = 0x00000002, // gets pushed around by the wind specials
MF2_BOUNCE1 = 0x00000004, //MF2_BOUNCE1 = 0x00000004,
MF2_BLASTED = 0x00000008, // actor will temporarily take damage from impact MF2_BLASTED = 0x00000008, // actor will temporarily take damage from impact
MF2_FLY = 0x00000010, // fly mode is active MF2_FLY = 0x00000010, // fly mode is active
MF2_FLOORCLIP = 0x00000020, // if feet are allowed to be clipped MF2_FLOORCLIP = 0x00000020, // if feet are allowed to be clipped
@ -176,7 +176,7 @@ enum
MF2_NODMGTHRUST = 0x00020000, // does not thrust target when damaging MF2_NODMGTHRUST = 0x00020000, // does not thrust target when damaging
MF2_TELESTOMP = 0x00040000, // mobj can stomp another MF2_TELESTOMP = 0x00040000, // mobj can stomp another
MF2_FLOATBOB = 0x00080000, // use float bobbing z movement MF2_FLOATBOB = 0x00080000, // use float bobbing z movement
MF2_BOUNCE2 = 0x00100000, //MF2_BOUNCE2 = 0x00100000,
MF2_IMPACT = 0x00200000, // an MF_MISSILE mobj can activate SPAC_IMPACT MF2_IMPACT = 0x00200000, // an MF_MISSILE mobj can activate SPAC_IMPACT
MF2_PUSHWALL = 0x00400000, // mobj can push walls MF2_PUSHWALL = 0x00400000, // mobj can push walls
MF2_MCROSS = 0x00800000, // can activate monster cross lines MF2_MCROSS = 0x00800000, // can activate monster cross lines
@ -198,11 +198,6 @@ enum
// DOOM - Like Hexen, but the bounce turns off if its vertical velocity // DOOM - Like Hexen, but the bounce turns off if its vertical velocity
// is too low. // is too low.
MF2_BOUNCETYPE = MF2_BOUNCE1|MF2_BOUNCE2,
MF2_NOBOUNCE = 0,
MF2_HERETICBOUNCE = MF2_BOUNCE1,
MF2_HEXENBOUNCE = MF2_BOUNCE2,
MF2_DOOMBOUNCE = MF2_BOUNCE1|MF2_BOUNCE2,
// --- mobj.flags3 --- // --- mobj.flags3 ---
@ -372,6 +367,23 @@ enum replace_t
ALLOW_REPLACE = 1 ALLOW_REPLACE = 1
}; };
enum EBounceType
{
BOUNCE_None=0,
BOUNCE_Doom=1,
BOUNCE_Heretic=2,
BOUNCE_Hexen=3,
BOUNCE_TypeMask = 3,
BOUNCE_UseSeeSound = 4, // compatibility fallback. Thios will only be
// set by the compatibility handlers for the old bounce flags.
// combined types
BOUNCE_DoomCompat = BOUNCE_Doom | BOUNCE_UseSeeSound,
BOUNCE_HereticCompat = BOUNCE_Heretic | BOUNCE_UseSeeSound,
BOUNCE_HexenCompat = BOUNCE_Hexen | BOUNCE_UseSeeSound,
};
// [RH] Like msecnode_t, but for the blockmap // [RH] Like msecnode_t, but for the blockmap
struct FBlockNode struct FBlockNode
{ {
@ -519,6 +531,9 @@ public:
// Actor just hit the floor // Actor just hit the floor
virtual void HitFloor (); virtual void HitFloor ();
// plays bouncing sound
void PlayBounceSound(bool onfloor);
// Called when an actor with MF_MISSILE and MF2_FLOORBOUNCE hits the floor // Called when an actor with MF_MISSILE and MF2_FLOORBOUNCE hits the floor
virtual bool FloorBounceMissile (secplane_t &plane); virtual bool FloorBounceMissile (secplane_t &plane);
@ -708,6 +723,7 @@ public:
// but instead tries to come closer for a melee attack. // but instead tries to come closer for a melee attack.
// This is not the same as meleerange // This is not the same as meleerange
fixed_t maxtargetrange; // any target farther away cannot be attacked fixed_t maxtargetrange; // any target farther away cannot be attacked
int bouncetype; // which bouncing type?
fixed_t bouncefactor; // Strife's grenades use 50%, Hexen's Flechettes 70. fixed_t bouncefactor; // Strife's grenades use 50%, Hexen's Flechettes 70.
fixed_t wallbouncefactor; // The bounce factor for walls can be different. fixed_t wallbouncefactor; // The bounce factor for walls can be different.
int bouncecount; // Strife's grenades only bounce twice before exploding int bouncecount; // Strife's grenades only bounce twice before exploding
@ -746,6 +762,8 @@ public:
FSoundIDNoInit DeathSound; FSoundIDNoInit DeathSound;
FSoundIDNoInit ActiveSound; FSoundIDNoInit ActiveSound;
FSoundIDNoInit UseSound; // [RH] Sound to play when an actor is used. FSoundIDNoInit UseSound; // [RH] Sound to play when an actor is used.
FSoundIDNoInit BounceSound;
FSoundIDNoInit WallBounceSound;
fixed_t Speed; fixed_t Speed;
fixed_t FloatSpeed; fixed_t FloatSpeed;

View file

@ -836,11 +836,10 @@ static int PatchThing (int thingy)
if (vchanged[1]) if (vchanged[1])
{ {
info->flags2 = value[1]; info->flags2 = value[1];
if (info->flags2 & MF2_BOUNCE1) if (info->flags2 & 0x00000004) // old BOUNCE1
{ // If a bex patch specifies FLOORBOUNCE, also set {
// BOUNCE2, because otherwise it will get HERETICBOUNCE info->flags2 &= ~4;
// instead of DOOMBOUNCE. info->bouncetype = BOUNCE_DoomCompat;
info->flags2 |= MF2_BOUNCE2;
} }
// Damage types that once were flags but now are not // Damage types that once were flags but now are not
if (info->flags2 & 0x20000000) if (info->flags2 & 0x20000000)

View file

@ -482,7 +482,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact)
{ // Bounce { // Bounce
self->health = MAGIC_JUNK; self->health = MAGIC_JUNK;
self->momz = (self->momz * 192) >> 8; self->momz = (self->momz * 192) >> 8;
self->flags2 &= ~MF2_BOUNCETYPE; self->bouncetype = BOUNCE_None;
self->SetState (self->SpawnState); self->SetState (self->SpawnState);
S_Sound (self, CHAN_BODY, "weapons/macebounce", 1, ATTN_NORM); S_Sound (self, CHAN_BODY, "weapons/macebounce", 1, ATTN_NORM);
} }
@ -558,7 +558,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2)
boom: boom:
self->momx = self->momy = self->momz = 0; self->momx = self->momy = self->momz = 0;
self->flags |= MF_NOGRAVITY; self->flags |= MF_NOGRAVITY;
self->flags2 &= ~MF2_BOUNCETYPE; self->bouncetype = BOUNCE_None;
self->gravity = FRACUNIT; self->gravity = FRACUNIT;
} }
} }

View file

@ -371,7 +371,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb2)
self->SetState (self->SpawnState + 6); self->SetState (self->SpawnState + 6);
self->z = self->floorz; self->z = self->floorz;
self->momz = 0; self->momz = 0;
self->flags2 &= ~MF2_BOUNCETYPE; self->bouncetype = BOUNCE_None;
self->flags &= ~MF_MISSILE; self->flags &= ~MF_MISSILE;
} }
CALL_ACTION(A_CheckThrowBomb, self); CALL_ACTION(A_CheckThrowBomb, self);

View file

@ -2621,7 +2621,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Die)
ACTION_PARAM_START(1); ACTION_PARAM_START(1);
ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_NAME(damagetype, 0);
P_DamageMobj (self, NULL, NULL, self->health, damagetype); P_DamageMobj (self, NULL, NULL, self->health, damagetype, DMG_FORCED);
} }
// //

View file

@ -911,7 +911,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
} }
return; return;
} }
if ((target->flags2 & MF2_INVULNERABLE) && damage < 1000000) if ((target->flags2 & MF2_INVULNERABLE) && damage < 1000000 && !(flags & DMG_FORCED))
{ // actor is invulnerable { // actor is invulnerable
if (!target->player) if (!target->player)
{ {
@ -945,69 +945,72 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
{ {
target->momx = target->momy = target->momz = 0; target->momx = target->momy = target->momz = 0;
} }
if (target->flags2 & MF2_DORMANT) if (!(flags & DMG_FORCED)) // DMG_FORCED skips all special damage checks
{ {
// Invulnerable, and won't wake up if (target->flags2 & MF2_DORMANT)
return;
}
player = target->player;
if (player && damage > 1)
{
// Take half damage in trainer mode
damage = FixedMul(damage, G_SkillProperty(SKILLP_DamageFactor));
}
// Special damage types
if (inflictor)
{
if (inflictor->flags4 & MF4_SPECTRAL)
{
if (player != NULL)
{
if (!deathmatch && inflictor->health == -1)
return;
}
else if (target->flags4 & MF4_SPECTRAL)
{
if (inflictor->health == -2 && !target->IsHostile(inflictor))
return;
}
}
damage = inflictor->DoSpecialDamage (target, damage);
if (damage == -1)
{ {
// Invulnerable, and won't wake up
return; return;
} }
player = target->player;
} if (player && damage > 1)
// Handle active damage modifiers (e.g. PowerDamage)
if (source != NULL && source->Inventory != NULL)
{
int olddam = damage;
source->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;
}
DmgFactors * df = target->GetClass()->ActorInfo->DamageFactors;
if (df != NULL)
{
fixed_t * pdf = df->CheckKey(mod);
if (pdf== NULL && mod != NAME_None) pdf = df->CheckKey(NAME_None);
if (pdf != NULL)
{ {
damage = FixedMul(damage, *pdf); // Take half damage in trainer mode
if (damage <= 0) return; damage = FixedMul(damage, G_SkillProperty(SKILLP_DamageFactor));
} }
} // Special damage types
if (inflictor)
{
if (inflictor->flags4 & MF4_SPECTRAL)
{
if (player != NULL)
{
if (!deathmatch && inflictor->health == -1)
return;
}
else if (target->flags4 & MF4_SPECTRAL)
{
if (inflictor->health == -2 && !target->IsHostile(inflictor))
return;
}
}
damage = target->TakeSpecialDamage (inflictor, source, damage, mod); damage = inflictor->DoSpecialDamage (target, damage);
if (damage == -1)
{
return;
}
}
// Handle active damage modifiers (e.g. PowerDamage)
if (source != NULL && source->Inventory != NULL)
{
int olddam = damage;
source->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;
}
DmgFactors * df = target->GetClass()->ActorInfo->DamageFactors;
if (df != NULL)
{
fixed_t * pdf = df->CheckKey(mod);
if (pdf== NULL && mod != NAME_None) pdf = df->CheckKey(NAME_None);
if (pdf != NULL)
{
damage = FixedMul(damage, *pdf);
if (damage <= 0) return;
}
}
damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
}
if (damage == -1) if (damage == -1)
{ {
@ -1076,11 +1079,6 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
// //
if (player) if (player)
{ {
if ((target->flags2 & MF2_INVULNERABLE) && damage < 1000000)
{ // player is invulnerable, so don't hurt him
return;
}
//Added by MC: Lets bots look allround for enemies if they survive an ambush. //Added by MC: Lets bots look allround for enemies if they survive an ambush.
if (player->isbot) if (player->isbot)
{ {
@ -1094,44 +1092,53 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
damage = target->health - 1; damage = target->health - 1;
} }
if (damage < 1000 && ((target->player->cheats & CF_GODMODE) if (!(flags & DMG_FORCED))
|| (target->player->mo->flags2 & MF2_INVULNERABLE)))
{ {
return; if ((target->flags2 & MF2_INVULNERABLE) && damage < 1000000)
} { // player is invulnerable, so don't hurt him
return;
// [RH] Avoid friendly fire if enabled
if (source != NULL && player != source->player && target->IsTeammate (source))
{
FriendlyFire = true;
if (damage < 1000000)
{ // Still allow telefragging :-(
damage = (int)((float)damage * level.teamdamage);
if (damage <= 0)
return;
} }
}
if (!(flags & DMG_NO_ARMOR) && player->mo->Inventory != NULL) if (damage < 1000 && ((target->player->cheats & CF_GODMODE)
{ || (target->player->mo->flags2 & MF2_INVULNERABLE)))
int newdam = damage;
player->mo->Inventory->AbsorbDamage (damage, mod, newdam);
damage = newdam;
if (damage <= 0)
{ {
return; return;
} }
// [RH] Avoid friendly fire if enabled
if (source != NULL && player != source->player && target->IsTeammate (source))
{
FriendlyFire = true;
if (damage < 1000000)
{ // Still allow telefragging :-(
damage = (int)((float)damage * level.teamdamage);
if (damage <= 0)
return;
}
}
if (!(flags & DMG_NO_ARMOR) && player->mo->Inventory != NULL)
{
int newdam = damage;
player->mo->Inventory->AbsorbDamage (damage, mod, newdam);
damage = newdam;
if (damage <= 0)
{
return;
}
}
if (damage >= player->health
&& (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch)
&& !player->morphTics)
{ // Try to use some inventory health
P_AutoUseHealth (player, damage - player->health + 1);
}
} }
if (damage >= player->health
&& (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch)
&& !player->morphTics)
{ // Try to use some inventory health
P_AutoUseHealth (player, damage - player->health + 1);
}
player->health -= damage; // mirror mobj health here for Dave player->health -= damage; // mirror mobj health here for Dave
// [RH] Make voodoo dolls and real players record the same health // [RH] Make voodoo dolls and real players record the same health
target->health = player->mo->health -= damage; target->health = player->mo->health -= damage;
if (player->health < 50 && !deathmatch) if (player->health < 50 && !deathmatch && !(flags & DMG_FORCED))
{ {
P_AutoUseStrifeHealth (player); P_AutoUseStrifeHealth (player);
player->mo->health = player->health; player->mo->health = player->health;
@ -1156,7 +1163,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
else else
{ {
// Armor for monsters. // Armor for monsters.
if (!(flags & DMG_NO_ARMOR) && target->Inventory != NULL && damage > 0) if (!(flags & (DMG_NO_ARMOR|DMG_FORCED)) && target->Inventory != NULL && damage > 0)
{ {
int newdam = damage; int newdam = damage;
target->Inventory->AbsorbDamage (damage, mod, newdam); target->Inventory->AbsorbDamage (damage, mod, newdam);

View file

@ -457,6 +457,7 @@ enum EDmgFlags
DMG_NO_ARMOR = 1, DMG_NO_ARMOR = 1,
DMG_INFLICTOR_IS_PUFF = 2, DMG_INFLICTOR_IS_PUFF = 2,
DMG_THRUSTLESS = 4, DMG_THRUSTLESS = 4,
DMG_FORCED = 8,
}; };

View file

@ -864,7 +864,8 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
return true; return true;
} }
if (tm.thing->flags2 & MF2_BOUNCE2) int bt = tm.thing->bouncetype & BOUNCE_TypeMask;
if (bt == BOUNCE_Doom || bt == BOUNCE_Hexen)
{ {
if (tm.thing->Damage == 0) if (tm.thing->Damage == 0)
{ {
@ -2494,7 +2495,8 @@ bool FSlide::BounceWall (AActor *mo)
fixed_t movelen; fixed_t movelen;
line_t *line; line_t *line;
if (!(mo->flags2 & MF2_BOUNCE2)) int bt = mo->bouncetype & BOUNCE_TypeMask;
if (bt != BOUNCE_Doom && bt != BOUNCE_Hexen)
{ {
return false; return false;
} }

View file

@ -268,6 +268,8 @@ void AActor::Serialize (FArchive &arc)
<< DeathSound << DeathSound
<< ActiveSound << ActiveSound
<< UseSound << UseSound
<< BounceSound
<< WallBounceSound
<< Speed << Speed
<< FloatSpeed << FloatSpeed
<< Mass << Mass
@ -278,6 +280,7 @@ void AActor::Serialize (FArchive &arc)
<< MissileState << MissileState
<< MaxDropOffHeight << MaxDropOffHeight
<< MaxStepHeight << MaxStepHeight
<< bouncetype
<< bouncefactor << bouncefactor
<< wallbouncefactor << wallbouncefactor
<< bouncecount << bouncecount
@ -1249,6 +1252,31 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
} }
} }
void AActor::PlayBounceSound(bool onfloor)
{
if (!onfloor && (flags3 & MF3_NOWALLBOUNCESND))
{
return;
}
if (!(flags4 & MF4_NOBOUNCESOUND))
{
if (bouncetype & BOUNCE_UseSeeSound)
{
S_Sound (this, CHAN_VOICE, SeeSound, 1, ATTN_IDLE);
}
else if (onfloor || WallBounceSound <= 0)
{
S_Sound (this, CHAN_VOICE, BounceSound, 1, ATTN_IDLE);
}
else
{
S_Sound (this, CHAN_VOICE, WallBounceSound, 1, ATTN_IDLE);
}
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// //
// PROC P_FloorBounceMissile // PROC P_FloorBounceMissile
@ -1281,8 +1309,10 @@ bool AActor::FloorBounceMissile (secplane_t &plane)
} }
fixed_t dot = TMulScale16 (momx, plane.a, momy, plane.b, momz, plane.c); fixed_t dot = TMulScale16 (momx, plane.a, momy, plane.b, momz, plane.c);
int bt = bouncetype & BOUNCE_TypeMask;
if ((flags2 & MF2_BOUNCETYPE) == MF2_HERETICBOUNCE)
if (bt == BOUNCE_Heretic)
{ {
momx -= MulScale15 (plane.a, dot); momx -= MulScale15 (plane.a, dot);
momy -= MulScale15 (plane.b, dot); momy -= MulScale15 (plane.b, dot);
@ -1301,16 +1331,12 @@ bool AActor::FloorBounceMissile (secplane_t &plane)
momz = MulScale30 (momz - MulScale15 (plane.c, dot), bouncescale); momz = MulScale30 (momz - MulScale15 (plane.c, dot), bouncescale);
angle = R_PointToAngle2 (0, 0, momx, momy); angle = R_PointToAngle2 (0, 0, momx, momy);
if (SeeSound && !(flags4 & MF4_NOBOUNCESOUND)) PlayBounceSound(true);
{ if (bt == BOUNCE_Doom)
S_Sound (this, CHAN_VOICE, SeeSound, 1, ATTN_IDLE);
}
if ((flags2 & MF2_BOUNCETYPE) == MF2_DOOMBOUNCE)
{ {
if (!(flags & MF_NOGRAVITY) && (momz < 3*FRACUNIT)) if (!(flags & MF_NOGRAVITY) && (momz < 3*FRACUNIT))
{ {
flags2 &= ~MF2_BOUNCETYPE; bouncetype = BOUNCE_None;
} }
} }
return false; return false;
@ -1705,7 +1731,8 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
steps = 0; steps = 0;
if (BlockingMobj) if (BlockingMobj)
{ {
if (mo->flags2 & MF2_BOUNCE2) int bt = mo->bouncetype & BOUNCE_TypeMask;
if (bt == BOUNCE_Doom || bt == BOUNCE_Hexen)
{ {
if (mo->flags5&MF5_BOUNCEONACTORS || if (mo->flags5&MF5_BOUNCEONACTORS ||
(BlockingMobj->flags2 & MF2_REFLECTIVE) || (BlockingMobj->flags2 & MF2_REFLECTIVE) ||
@ -1723,10 +1750,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
angle >>= ANGLETOFINESHIFT; angle >>= ANGLETOFINESHIFT;
mo->momx = FixedMul (speed, finecosine[angle]); mo->momx = FixedMul (speed, finecosine[angle]);
mo->momy = FixedMul (speed, finesine[angle]); mo->momy = FixedMul (speed, finesine[angle]);
if (mo->SeeSound && !(mo->flags4&MF4_NOBOUNCESOUND)) mo->PlayBounceSound(true);
{
S_Sound (mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_IDLE);
}
return oldfloorz; return oldfloorz;
} }
else else
@ -1741,10 +1765,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
// Struck a wall // Struck a wall
if (P_BounceWall (mo)) if (P_BounceWall (mo))
{ {
if (mo->SeeSound && !(mo->flags3 & MF3_NOWALLBOUNCESND)) mo->PlayBounceSound(false);
{
S_Sound (mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_IDLE);
}
return oldfloorz; return oldfloorz;
} }
} }
@ -2074,7 +2095,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
(!(gameinfo.gametype & GAME_DoomChex) || !(mo->flags & MF_NOCLIP))) (!(gameinfo.gametype & GAME_DoomChex) || !(mo->flags & MF_NOCLIP)))
{ {
mo->z = mo->floorz; mo->z = mo->floorz;
if (mo->flags2 & MF2_BOUNCETYPE) if (mo->bouncetype != BOUNCE_None)
{ {
mo->FloorBounceMissile (mo->floorsector->floorplane); mo->FloorBounceMissile (mo->floorsector->floorplane);
return; return;
@ -2167,7 +2188,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
if (mo->z + mo->height > mo->ceilingz) if (mo->z + mo->height > mo->ceilingz)
{ {
mo->z = mo->ceilingz - mo->height; mo->z = mo->ceilingz - mo->height;
if (mo->flags2 & MF2_BOUNCETYPE) if (mo->bouncetype != BOUNCE_None)
{ // ceiling bounce { // ceiling bounce
mo->FloorBounceMissile (mo->ceilingsector->ceilingplane); mo->FloorBounceMissile (mo->ceilingsector->ceilingplane);
return; return;

View file

@ -552,15 +552,15 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
} }
else if (def == DEF_Projectile && sc.Compare ("DoomBounce")) else if (def == DEF_Projectile && sc.Compare ("DoomBounce"))
{ {
defaults->flags2 = (defaults->flags2 & ~MF2_BOUNCETYPE) | MF2_DOOMBOUNCE; defaults->bouncetype = BOUNCE_DoomCompat;
} }
else if (def == DEF_Projectile && sc.Compare ("HereticBounce")) else if (def == DEF_Projectile && sc.Compare ("HereticBounce"))
{ {
defaults->flags2 = (defaults->flags2 & ~MF2_BOUNCETYPE) | MF2_HERETICBOUNCE; defaults->bouncetype = BOUNCE_HereticCompat;
} }
else if (def == DEF_Projectile && sc.Compare ("HexenBounce")) else if (def == DEF_Projectile && sc.Compare ("HexenBounce"))
{ {
defaults->flags2 = (defaults->flags2 & ~MF2_BOUNCETYPE) | MF2_HEXENBOUNCE; defaults->bouncetype = BOUNCE_HexenCompat;
} }
else if (def == DEF_Pickup && sc.Compare ("PickupSound")) else if (def == DEF_Pickup && sc.Compare ("PickupSound"))
{ {

View file

@ -208,6 +208,9 @@ enum
DEPF_PICKUPFLASH, DEPF_PICKUPFLASH,
DEPF_QUARTERGRAVITY, DEPF_QUARTERGRAVITY,
DEPF_FIRERESIST, DEPF_FIRERESIST,
DEPF_HERETICBOUNCE,
DEPF_HEXENBOUNCE,
DEPF_DOOMBOUNCE,
}; };
enum enum

View file

@ -1882,7 +1882,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CountdownArg)
} }
else if (self->flags&MF_SHOOTABLE) else if (self->flags&MF_SHOOTABLE)
{ {
P_DamageMobj (self, NULL, NULL, self->health, NAME_None); P_DamageMobj (self, NULL, NULL, self->health, NAME_None, DMG_FORCED);
} }
else else
{ {

View file

@ -94,7 +94,6 @@ static FFlagDef ActorFlags[]=
DEFINE_FLAG(MF, ICECORPSE, AActor, flags), DEFINE_FLAG(MF, ICECORPSE, AActor, flags),
DEFINE_FLAG(MF2, DONTREFLECT, AActor, flags2), DEFINE_FLAG(MF2, DONTREFLECT, AActor, flags2),
DEFINE_FLAG(MF2, WINDTHRUST, AActor, flags2), DEFINE_FLAG(MF2, WINDTHRUST, AActor, flags2),
DEFINE_FLAG(MF2, HERETICBOUNCE , AActor, flags2),
DEFINE_FLAG(MF2, BLASTED, AActor, flags2), DEFINE_FLAG(MF2, BLASTED, AActor, flags2),
DEFINE_FLAG(MF2, FLOORCLIP, AActor, flags2), DEFINE_FLAG(MF2, FLOORCLIP, AActor, flags2),
DEFINE_FLAG(MF2, SPAWNFLOAT, AActor, flags2), DEFINE_FLAG(MF2, SPAWNFLOAT, AActor, flags2),
@ -110,8 +109,6 @@ static FFlagDef ActorFlags[]=
DEFINE_FLAG(MF2, DONTTRANSLATE, AActor, flags2), DEFINE_FLAG(MF2, DONTTRANSLATE, AActor, flags2),
DEFINE_FLAG(MF2, TELESTOMP, AActor, flags2), DEFINE_FLAG(MF2, TELESTOMP, AActor, flags2),
DEFINE_FLAG(MF2, FLOATBOB, AActor, flags2), DEFINE_FLAG(MF2, FLOATBOB, AActor, flags2),
DEFINE_FLAG(MF2, HEXENBOUNCE, AActor, flags2),
DEFINE_FLAG(MF2, DOOMBOUNCE, AActor, flags2),
DEFINE_FLAG2(MF2_IMPACT, ACTIVATEIMPACT, AActor, flags2), DEFINE_FLAG2(MF2_IMPACT, ACTIVATEIMPACT, AActor, flags2),
DEFINE_FLAG2(MF2_PUSHWALL, CANPUSHWALLS, AActor, flags2), DEFINE_FLAG2(MF2_PUSHWALL, CANPUSHWALLS, AActor, flags2),
DEFINE_FLAG2(MF2_MCROSS, ACTIVATEMCROSS, AActor, flags2), DEFINE_FLAG2(MF2_MCROSS, ACTIVATEMCROSS, AActor, flags2),
@ -226,6 +223,9 @@ static FFlagDef ActorFlags[]=
DEFINE_DEPRECATED_FLAG(LONGMELEERANGE), DEFINE_DEPRECATED_FLAG(LONGMELEERANGE),
DEFINE_DEPRECATED_FLAG(QUARTERGRAVITY), DEFINE_DEPRECATED_FLAG(QUARTERGRAVITY),
DEFINE_DEPRECATED_FLAG(FIRERESIST), DEFINE_DEPRECATED_FLAG(FIRERESIST),
DEFINE_DEPRECATED_FLAG(HERETICBOUNCE),
DEFINE_DEPRECATED_FLAG(HEXENBOUNCE),
DEFINE_DEPRECATED_FLAG(DOOMBOUNCE),
DEFINE_DUMMY_FLAG(NONETID), DEFINE_DUMMY_FLAG(NONETID),
DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN), DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN),
DEFINE_DUMMY_FLAG(CLIENTSIDEONLY), DEFINE_DUMMY_FLAG(CLIENTSIDEONLY),

View file

@ -129,6 +129,16 @@ void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int ind
case DEPF_FIRERESIST: case DEPF_FIRERESIST:
info->SetDamageFactor(NAME_Fire, set? FRACUNIT/2 : FRACUNIT); info->SetDamageFactor(NAME_Fire, set? FRACUNIT/2 : FRACUNIT);
break; break;
// the bounce flags will set the compatibility bounce modes to remain compatible
case DEPF_HERETICBOUNCE:
defaults->bouncetype = set? BOUNCE_HereticCompat : 0;
break;
case DEPF_HEXENBOUNCE:
defaults->bouncetype = set? BOUNCE_HexenCompat : 0;
break;
case DEPF_DOOMBOUNCE:
defaults->bouncetype = set? BOUNCE_DoomCompat : 0;
break;
case DEPF_PICKUPFLASH: case DEPF_PICKUPFLASH:
if (set) if (set)
{ {
@ -803,6 +813,16 @@ DEFINE_PROPERTY(bloodtype, Sss, Actor)
info->Class->Meta.SetMetaInt (AMETA_BloodType3, blood); info->Class->Meta.SetMetaInt (AMETA_BloodType3, blood);
} }
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(bouncetype, S, Actor)
{
const char *names[] = { "None", "Doom", "Heretic", "Hexen", "*", "DoomCompat", "HereticCompat", "HexenCompat", NULL };
PROP_STRING_PARM(id, 0);
defaults->bouncetype = MatchString(id, names);
}
//========================================================================== //==========================================================================
// //
//========================================================================== //==========================================================================
@ -1233,6 +1253,24 @@ DEFINE_CLASS_PROPERTY(usesound, S, Inventory)
defaults->UseSound = str; defaults->UseSound = str;
} }
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY(bouncesound, S, Inventory)
{
PROP_STRING_PARM(str, 0);
defaults->BounceSound = str;
}
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY(wallbouncesound, S, Inventory)
{
PROP_STRING_PARM(str, 0);
defaults->WallBounceSound = str;
}
//========================================================================== //==========================================================================
// //
//========================================================================== //==========================================================================

View file

@ -75,7 +75,7 @@
// SAVESIG should match SAVEVER. // SAVESIG should match SAVEVER.
// MINSAVEVER is the minimum level snapshot version that can be loaded. // MINSAVEVER is the minimum level snapshot version that can be loaded.
#define MINSAVEVER 1586 #define MINSAVEVER 1599
#if SVN_REVISION_NUMBER < MINSAVEVER #if SVN_REVISION_NUMBER < MINSAVEVER
// Never write a savegame with a version lower than what we need // Never write a savegame with a version lower than what we need

View file

@ -556,7 +556,7 @@ ACTOR MaceFX1
Damage 2 Damage 2
Projectile Projectile
+THRUGHOST +THRUGHOST
+HERETICBOUNCE BounceType "HereticCompat"
SeeSound "weapons/maceshoot" SeeSound "weapons/maceshoot"
action native A_MacePL1Check(); action native A_MacePL1Check();
@ -633,7 +633,7 @@ ACTOR MaceFX4 native
-NOGRAVITY -NOGRAVITY
+TELESTOMP +TELESTOMP
+THRUGHOST +THRUGHOST
+HERETICBOUNCE BounceType "HereticCompat"
SeeSound "" SeeSound ""
action native A_DeathBallImpact(); action native A_DeathBallImpact();

View file

@ -58,7 +58,7 @@ ACTOR ThrowingBomb
Height 10 Height 10
DamageType "Fire" DamageType "Fire"
+NOBLOCKMAP +DROPOFF +MISSILE +NOBLOCKMAP +DROPOFF +MISSILE
+HEXENBOUNCE BounceType "HexenCompat"
SeeSound "FlechetteBounce" SeeSound "FlechetteBounce"
DeathSound "FlechetteExplode" DeathSound "FlechetteExplode"

View file

@ -83,7 +83,7 @@ ACTOR SorcBall native
+FULLVOLDEATH +FULLVOLDEATH
+CANBOUNCEWATER +CANBOUNCEWATER
+NOWALLBOUNCESND +NOWALLBOUNCESND
+HEXENBOUNCE BounceType "HexenCompat"
SeeSound "SorcererBallBounce" SeeSound "SorcererBallBounce"
DeathSound "SorcererBigBallExplode" DeathSound "SorcererBigBallExplode"

View file

@ -176,7 +176,7 @@ ACTOR GlassShard native
Projectile Projectile
-ACTIVATEPCROSS -ACTIVATEPCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE BounceType "HexenCompat"
BounceFactor 0.3 BounceFactor 0.3
} }

View file

@ -642,11 +642,10 @@ ACTOR HEGrenade
Projectile Projectile
-NOGRAVITY -NOGRAVITY
+STRIFEDAMAGE +STRIFEDAMAGE
+NOBOUNCESOUND
+BOUNCEONACTORS +BOUNCEONACTORS
+EXPLODEONWATER +EXPLODEONWATER
+DOOMBOUNCE
MaxStepHeight 4 MaxStepHeight 4
BounceType "Doom"
BounceFactor 0.5 BounceFactor 0.5
BounceCount 2 BounceCount 2
SeeSound "weapons/hegrenadeshoot" SeeSound "weapons/hegrenadeshoot"
@ -680,10 +679,9 @@ ACTOR PhosphorousGrenade
Projectile Projectile
-NOGRAVITY -NOGRAVITY
+STRIFEDAMAGE +STRIFEDAMAGE
+NOBOUNCESOUND
+BOUNCEONACTORS +BOUNCEONACTORS
+EXPLODEONWATER +EXPLODEONWATER
+DOOMBOUNCE BounceType "Doom"
MaxStepHeight 4 MaxStepHeight 4
BounceFactor 0.5 BounceFactor 0.5
BounceCount 2 BounceCount 2