- 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
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
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)
- 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

View file

@ -155,7 +155,7 @@ enum
MF2_DONTREFLECT = 0x00000001, // this projectile cannot be reflected
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_FLY = 0x00000010, // fly mode is active
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_TELESTOMP = 0x00040000, // mobj can stomp another
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_PUSHWALL = 0x00400000, // mobj can push walls
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
// 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 ---
@ -372,6 +367,23 @@ enum replace_t
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
struct FBlockNode
{
@ -519,6 +531,9 @@ public:
// Actor just hit the floor
virtual void HitFloor ();
// plays bouncing sound
void PlayBounceSound(bool onfloor);
// Called when an actor with MF_MISSILE and MF2_FLOORBOUNCE hits the floor
virtual bool FloorBounceMissile (secplane_t &plane);
@ -708,6 +723,7 @@ public:
// but instead tries to come closer for a melee attack.
// This is not the same as meleerange
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 wallbouncefactor; // The bounce factor for walls can be different.
int bouncecount; // Strife's grenades only bounce twice before exploding
@ -746,6 +762,8 @@ public:
FSoundIDNoInit DeathSound;
FSoundIDNoInit ActiveSound;
FSoundIDNoInit UseSound; // [RH] Sound to play when an actor is used.
FSoundIDNoInit BounceSound;
FSoundIDNoInit WallBounceSound;
fixed_t Speed;
fixed_t FloatSpeed;

View file

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

View file

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

View file

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

View file

@ -2621,7 +2621,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Die)
ACTION_PARAM_START(1);
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;
}
if ((target->flags2 & MF2_INVULNERABLE) && damage < 1000000)
if ((target->flags2 & MF2_INVULNERABLE) && damage < 1000000 && !(flags & DMG_FORCED))
{ // actor is invulnerable
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;
}
if (target->flags2 & MF2_DORMANT)
if (!(flags & DMG_FORCED)) // DMG_FORCED skips all special damage checks
{
// Invulnerable, and won't wake up
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)
if (target->flags2 & MF2_DORMANT)
{
// Invulnerable, and won't wake up
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)
player = target->player;
if (player && damage > 1)
{
damage = FixedMul(damage, *pdf);
if (damage <= 0) return;
// 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 = 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)
{
@ -1076,11 +1079,6 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
//
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.
if (player->isbot)
{
@ -1094,44 +1092,53 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
damage = target->health - 1;
}
if (damage < 1000 && ((target->player->cheats & CF_GODMODE)
|| (target->player->mo->flags2 & MF2_INVULNERABLE)))
if (!(flags & DMG_FORCED))
{
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 ((target->flags2 & MF2_INVULNERABLE) && damage < 1000000)
{ // player is invulnerable, so don't hurt him
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)
if (damage < 1000 && ((target->player->cheats & CF_GODMODE)
|| (target->player->mo->flags2 & MF2_INVULNERABLE)))
{
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
// [RH] Make voodoo dolls and real players record the same health
target->health = player->mo->health -= damage;
if (player->health < 50 && !deathmatch)
if (player->health < 50 && !deathmatch && !(flags & DMG_FORCED))
{
P_AutoUseStrifeHealth (player);
player->mo->health = player->health;
@ -1156,7 +1163,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
else
{
// 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;
target->Inventory->AbsorbDamage (damage, mod, newdam);

View file

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

View file

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

View file

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

View file

@ -552,15 +552,15 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
}
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"))
{
defaults->flags2 = (defaults->flags2 & ~MF2_BOUNCETYPE) | MF2_HERETICBOUNCE;
defaults->bouncetype = BOUNCE_HereticCompat;
}
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"))
{

View file

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

View file

@ -1882,7 +1882,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CountdownArg)
}
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
{

View file

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

View file

@ -129,6 +129,16 @@ void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int ind
case DEPF_FIRERESIST:
info->SetDamageFactor(NAME_Fire, set? FRACUNIT/2 : FRACUNIT);
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:
if (set)
{
@ -803,6 +813,16 @@ DEFINE_PROPERTY(bloodtype, Sss, Actor)
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;
}
//==========================================================================
//
//==========================================================================
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.
// MINSAVEVER is the minimum level snapshot version that can be loaded.
#define MINSAVEVER 1586
#define MINSAVEVER 1599
#if SVN_REVISION_NUMBER < MINSAVEVER
// Never write a savegame with a version lower than what we need

View file

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

View file

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

View file

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

View file

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

View file

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