diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 7a3c73ad1..5909da9aa 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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. diff --git a/src/actor.h b/src/actor.h index 8dbfdf194..b6dab786a 100644 --- a/src/actor.h +++ b/src/actor.h @@ -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 --- diff --git a/src/c_console.cpp b/src/c_console.cpp index 324fad660..aafc76f36 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -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) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 3cf59f16e..cfa5cdbae 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -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) { diff --git a/src/g_doom/a_scriptedmarine.cpp b/src/g_doom/a_scriptedmarine.cpp index 763fd26b9..701a0930f 100644 --- a/src/g_doom/a_scriptedmarine.cpp +++ b/src/g_doom/a_scriptedmarine.cpp @@ -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; } diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index 767d282b8..5dcdd0c28 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -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 (4, (self->radius>>FRACBITS)*(self->height>>FRACBITS)/32); i = (pr_freeze.Random2()) % (numChunks/4); for (i = MAX (24, numChunks + i); i >= 0; i--) diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 6c53fa247..97526bf67 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -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); } } diff --git a/src/g_strife/a_templar.cpp b/src/g_strife/a_templar.cpp index afdac2e15..a6a733a00 100644 --- a/src/g_strife/a_templar.cpp +++ b/src/g_strife/a_templar.cpp @@ -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); } } diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 003e0077e..3b1521f8c 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -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; diff --git a/src/p_map.cpp b/src/p_map.cpp index e401e84fb..dc056972f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -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) && diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 5705fb77b..b275539b6 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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) diff --git a/src/p_user.cpp b/src/p_user.cpp index 374442a18..82914b1f6 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -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; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index cf8a2f5e4..1c00e7ae5 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -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) diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 6226bd0df..6d9419f97 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -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; } //==========================================================================