mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 04:51:19 +00:00
- 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:
parent
ba106c28c4
commit
fdec06ff9b
14 changed files with 62 additions and 23 deletions
|
@ -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.
|
||||
|
|
|
@ -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 ---
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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--)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
Loading…
Reference in a new issue