- fixed:P_DamageMobj just set an ice corpse's velocity to 0 to make it shatter.

But that's insufficient because it doesn't factor in any subsequent velocity
  change that happens between the damaging and the next call to A_FreezeDeathChunks.
- fixed: The TimeFreezer did not freeze other players' controls in a
  multiplayer game.
- fixed: DECORATE's 'gravity' property incorrectly messed around with the
  NOGRAVITY flag.
- fixed: Hitscan attacks didn't check the puff's replacement for damage types.


SVN r2026 (trunk)
This commit is contained in:
Christoph Oelckers 2009-12-16 16:09:48 +00:00
parent ba106c28c4
commit fdec06ff9b
14 changed files with 62 additions and 23 deletions

View file

@ -1,3 +1,13 @@
December 16, 2009 (Changes by Graf Zahl)
- fixed:P_DamageMobj just set an ice corpse's velocity to 0 to make it shatter.
But that's insufficient because it doesn't factor in any subsequent velocity
change that happens between the damaging and the next call to A_FreezeDeathChunks.
- fixed: The TimeFreezer did not freeze other players' controls in a
multiplayer game.
- fixed: DECORATE's 'gravity' property incorrectly messed around with the
NOGRAVITY flag.
- fixed: Hitscan attacks didn't check the puff's replacement for damage types.
December 13, 2009 (Changes by Graf Zahl)
- fixed: old-style DECORATE definitions with non-alphanumeric characters in
the name produced an error.

View file

@ -317,6 +317,7 @@ enum
MF6_FALLING = 0x00004000, // From MBF: Object is falling (for pseudotorque simulation)
MF6_LINEDONE = 0x00008000, // From MBF: Object has already run a line effect
MF6_NOTRIGGER = 0x00010000, // actor cannot trigger any line actions
MF6_SHATTERING = 0x00020000, // marks an ice corpse for forced shattering
// --- mobj.renderflags ---

View file

@ -81,6 +81,7 @@ static bool C_TabCompleteList ();
static bool TabbedLast; // True if last key pressed was tab
static bool TabbedList; // True if tab list was shown
CVAR (Bool, con_notablist, false, CVAR_ARCHIVE)
CVAR (Bool, con_ticker, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
static FTextureID conback;
static DWORD conshade;
@ -1104,17 +1105,23 @@ static void C_DrawNotifyText ()
void C_InitTicker (const char *label, unsigned int max, bool showpercent)
{
TickerPercent = showpercent;
TickerMax = max;
TickerLabel = label;
TickerAt = 0;
maybedrawnow (true, false);
if (con_ticker)
{
TickerPercent = showpercent;
TickerMax = max;
TickerLabel = label;
TickerAt = 0;
maybedrawnow (true, false);
}
}
void C_SetTicker (unsigned int at, bool forceUpdate)
{
TickerAt = at > TickerMax ? TickerMax : at;
maybedrawnow (true, TickerVisible ? forceUpdate : false);
if (con_ticker)
{
TickerAt = at > TickerMax ? TickerMax : at;
maybedrawnow (true, TickerVisible ? forceUpdate : false);
}
}
void C_DrawConsole (bool hw2d)

View file

@ -133,7 +133,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
// use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states)
P_LineAttack (self, angle, MELEERANGE+1,
P_AimLineAttack (self, angle, MELEERANGE+1, &linetarget), damage,
GetDefaultByType(pufftype)->DamageType, pufftype);
NAME_None, pufftype);
if (!linetarget)
{

View file

@ -442,7 +442,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
P_LineAttack (self, angle, MISSILERANGE,
pitch + (pr_m_fireshotgun2.Random2() * 332063), damage,
NAME_None, PClass::FindClass(NAME_BulletPuff));
NAME_None, NAME_BulletPuff);
}
self->special1 = level.maptime;
}

View file

@ -233,18 +233,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
int numChunks;
AActor *mo;
if (self->velx || self->vely || self->velz)
if ((self->velx || self->vely || self->velz) && !(self->flags6 & MF6_SHATTERING))
{
self->tics = 3*TICRATE;
return;
}
self->velx = self->vely = self->velz = 0;
S_Sound (self, CHAN_BODY, "misc/icebreak", 1, ATTN_NORM);
// [RH] In Hexen, this creates a random number of shards (range [24,56])
// with no relation to the size of the self shattering. I think it should
// base the number of shards on the size of the dead thing, so bigger
// things break up into more shards than smaller things.
// An self with radius 20 and height 64 creates ~40 chunks.
// An actor with radius 20 and height 64 creates ~40 chunks.
numChunks = MAX<int> (4, (self->radius>>FRACBITS)*(self->height>>FRACBITS)/32);
i = (pr_freeze.Random2()) % (numChunks/4);
for (i = MAX (24, numChunks + i); i >= 0; i--)

View file

@ -429,7 +429,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler1)
// it should use a different puff. ZDoom's default range is longer
// than this, so let's not handicap it by being too faithful to the
// original.
P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Disintegrate, NAME_MaulerPuff);
P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_None, NAME_MaulerPuff);
}
}

View file

@ -30,6 +30,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_TemplarAttack)
damage = (pr_templar() & 4) * 2;
angle = self->angle + (pr_templar.Random2() << 19);
pitchdiff = pr_templar.Random2() * 332063;
P_LineAttack (self, angle, MISSILERANGE+64*FRACUNIT, pitch+pitchdiff, damage, NAME_Disintegrate, NAME_MaulerPuff);
P_LineAttack (self, angle, MISSILERANGE+64*FRACUNIT, pitch+pitchdiff, damage, NAME_None, NAME_MaulerPuff);
}
}

View file

@ -906,6 +906,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
else if (target->flags & MF_ICECORPSE) // frozen
{
target->tics = 1;
target->flags6 |= MF6_SHATTERING;
target->velx = target->vely = target->velz = 0;
}
return;

View file

@ -3325,9 +3325,16 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
t1->player->ReadyWeapon != NULL &&
(t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST));
// Need to check defaults of replacement here
// We need to check the defaults of the replacement here
AActor *puffDefaults = GetDefaultByType(pufftype->ActorInfo->GetReplacement()->Class);
// if the puff uses a non-standard damage type this will override default and melee damage type.
// All other explicitly passed damage types (currenty only MDK) will be preserved.
if ((damageType == NAME_None || damageType == NAME_Melee) && puffDefaults->DamageType != NAME_None)
{
damageType = puffDefaults->DamageType;
}
int tflags;
if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) tflags = TRACE_NoSky;
else tflags = TRACE_NoSky|TRACE_Impact;
@ -3417,14 +3424,14 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
hitz = shootz + FixedMul (vz, trace.Distance);
// Spawn bullet puffs or blood spots, depending on target type.
AActor *puffDefaults = GetDefaultByType (pufftype);
if ((puffDefaults->flags3 & MF3_PUFFONACTORS) ||
(trace.Actor->flags & MF_NOBLOOD) ||
(trace.Actor->flags2 & (MF2_INVULNERABLE|MF2_DORMANT)))
{
// We must pass the unreplaced puff type here
puff = P_SpawnPuff (t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, flags|PF_HITTHING);
}
if (!(GetDefaultByType(pufftype)->flags3&MF3_BLOODLESSIMPACT))
if (!(puffDefaults->flags3&MF3_BLOODLESSIMPACT))
{
if (!bloodsplatter && !axeBlood &&
!(trace.Actor->flags & MF_NOBLOOD) &&

View file

@ -3486,6 +3486,9 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
actor->picnum.SetInvalid();
actor->health = actor->SpawnHealth();
// Actors with zero gravity need the NOGRAVITY flag set.
if (actor->gravity == 0) actor->flags |= MF_NOGRAVITY;
FRandom &rng = bglobal.m_Thinking ? pr_botspawnmobj : pr_spawnmobj;
if (actor->isFast() && actor->flags3 & MF3_ISMONSTER)

View file

@ -614,6 +614,12 @@ bool APlayerPawn::UseInventory (AInventory *item)
{ // You can't use items if you're totally frozen
return false;
}
if (( level.flags2 & LEVEL2_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE )))
{
// Time frozen
return false;
}
if (!Super::UseInventory (item))
{
// Heretic and Hexen advance the inventory cursor if the use failed.
@ -2053,8 +2059,12 @@ void P_PlayerThink (player_t *player)
player->mo->flags &= ~MF_JUSTATTACKED;
}
bool totallyfrozen = (player->cheats & CF_TOTALLYFROZEN || gamestate == GS_TITLELEVEL ||
(( level.flags2 & LEVEL2_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE )))
);
// [RH] Being totally frozen zeros out most input parameters.
if (player->cheats & CF_TOTALLYFROZEN || gamestate == GS_TITLELEVEL)
if (totallyfrozen)
{
if (gamestate == GS_TITLELEVEL)
{
@ -2086,7 +2096,7 @@ void P_PlayerThink (player_t *player)
}
if (player->morphTics == 0 && player->health > 0 && level.IsCrouchingAllowed())
{
if (!(player->cheats & CF_TOTALLYFROZEN))
if (!totallyfrozen)
{
int crouchdir = player->crouching;

View file

@ -834,7 +834,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
int angle = bangle + pr_cabullet.Random2() * (Spread_XY / 255);
int slope = bslope + pr_cabullet.Random2() * (Spread_Z / 255);
int damage = ((pr_cabullet()%3)+1) * DamagePerBullet;
P_LineAttack(self, angle, Range, slope, damage, GetDefaultByType(pufftype)->DamageType, pufftype);
P_LineAttack(self, angle, Range, slope, damage, NAME_None, pufftype);
}
}
}
@ -986,7 +986,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
if ((NumberOfBullets==1 && !player->refire) || NumberOfBullets==0)
{
int damage = ((pr_cwbullet()%3)+1)*DamagePerBullet;
P_LineAttack(self, bangle, Range, bslope, damage, GetDefaultByType(PuffType)->DamageType, PuffType);
P_LineAttack(self, bangle, Range, bslope, damage, NAME_None, PuffType);
}
else
{
@ -996,7 +996,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
int angle = bangle + pr_cwbullet.Random2() * (Spread_XY / 255);
int slope = bslope + pr_cwbullet.Random2() * (Spread_Z / 255);
int damage = ((pr_cwbullet()%3)+1) * DamagePerBullet;
P_LineAttack(self, angle, Range, slope, damage, GetDefaultByType(PuffType)->DamageType, PuffType);
P_LineAttack(self, angle, Range, slope, damage, NAME_None, PuffType);
}
}
}
@ -1104,7 +1104,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
if (!PuffType) PuffType = PClass::FindClass(NAME_BulletPuff);
P_LineAttack (self, angle, Range, pitch, Damage, GetDefaultByType(PuffType)->DamageType, PuffType, true);
P_LineAttack (self, angle, Range, pitch, Damage, NAME_None, PuffType, true);
// turn to face target
if (linetarget)

View file

@ -1026,7 +1026,6 @@ DEFINE_PROPERTY(gravity, F, Actor)
if (i < 0) I_Error ("Gravity must not be negative.");
defaults->gravity = i;
if (i == 0) defaults->flags |= MF_NOGRAVITY;
}
//==========================================================================