diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 769f4620f..d62310338 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,36 @@ +March 13, 2006 +- Fixed: ActorFlagSetOrReset() wasn't receiving the + or - character from + ParseActorProperties(). +- Fixed: The decorate FindFlag() function returned flags from ActorFlags + instead of the passed flags set. +- Fixed: The CHT_CHAINSAW, CHT_POWER, CHT_HEALTH, and CHT_RESSURECT needed + NULL player->mo checks. +- Fixed: The "give all" command didn't give the backpack in Doom, and it + must give the backpack before giving ammo. +- Fixed: P_SetPsprite() must not call the action function if the player is + not attached to an actor. This can happen, for instance, if the level is + destroyed while the player is holding a powered-up Phoenix Rod. As part + of its EndPowerup() function, it sets the psprite to the regular version, + but the player actor has already been destroyed. +- Fixed: FinishThingdef() needs to check for valid names, because weapons + could have inherited valid pointers from their superclass. +- Fixed: fuglyname didn't work. +- Fixed: Redefining $ambient sounds leaked memory. +- Added Jim's crashcatcher.c fix for better shell support. +- VC7.1 seems to have no trouble distinguishing between passing a (const + TypeInfo *) reference to operator<< and the generic, templated (object *) + version, so a few places that can benefit from it now use it. I believe + VC6 had problems with this, which is why I didn't do it all along. The + function's implementation was also moved out of dobject.cpp and into + farchive.cpp. +- Fixed: UnpackPixels() unpacked all chunks in a byte, which is wrong for the + last byte in a row if the image width is not an even multiple of the number + pixels per byte. +- Fixed: P_TranslateLineDef() should only clear monster activation for secret + useable lines, not crossable lines. +- Fixed: Some leftover P_IsHostile() calls still needed to be rewritten. +- Fixed: AWeaponHolder::Serialize() wrote the class type in all circumstances. + March 12, 2006 - Fixed: A_SpawnItem() should use CopyFriendliness(). - Fixed: AExplosiveBarrel should have MF2_MCROSS set. diff --git a/src/dobject.cpp b/src/dobject.cpp index f690a542c..55eaad506 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -702,19 +702,6 @@ void DObject::CheckIfSerialized () const } } -FArchive &operator<< (FArchive &arc, const TypeInfo * &info) -{ - if (arc.IsStoring ()) - { - arc.UserWriteClass (info); - } - else - { - arc.UserReadClass (info); - } - return arc; -} - ADD_STAT (destroys, out) { sprintf (out, "Pointer fixing: %d in %04.1f ms", diff --git a/src/farchive.cpp b/src/farchive.cpp index 678e81e34..b89e74213 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -1420,3 +1420,16 @@ void FArchive::UserReadClass (const TypeInfo *&type) break; } } + +FArchive &operator<< (FArchive &arc, const TypeInfo * &info) +{ + if (arc.IsStoring ()) + { + arc.UserWriteClass (info); + } + else + { + arc.UserReadClass (info); + } + return arc; +} diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 4058159c6..e31eec214 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -1337,7 +1337,6 @@ void A_FireBFG (AActor *actor) player->userinfo.aimdist = storedaimdist; } -bool thebfugu; int EvalExpressionI (int id, AActor *self); // // A_BFGSpray diff --git a/src/g_hexen/a_heresiarch.cpp b/src/g_hexen/a_heresiarch.cpp index 34c09fc06..9d5fcda34 100644 --- a/src/g_hexen/a_heresiarch.cpp +++ b/src/g_hexen/a_heresiarch.cpp @@ -150,14 +150,7 @@ END_DEFAULTS void AHeresiarch::Serialize (FArchive &arc) { Super::Serialize (arc); - if (arc.IsStoring()) - { - arc.UserWriteClass (StopBall); - } - else - { - arc.UserReadClass (StopBall); - } + arc << StopBall; } void AHeresiarch::Die (AActor *source, AActor *inflictor) diff --git a/src/g_hexen/a_hexenspecialdecs.cpp b/src/g_hexen/a_hexenspecialdecs.cpp index a8b908469..549177e3a 100644 --- a/src/g_hexen/a_hexenspecialdecs.cpp +++ b/src/g_hexen/a_hexenspecialdecs.cpp @@ -10,6 +10,7 @@ #include "s_sound.h" #include "p_local.h" #include "p_lnspec.h" +#include "a_hexenglobal.h" static FRandom pr_pottery ("PotteryExplode"); static FRandom pr_bit ("PotteryChooseBit"); diff --git a/src/g_hexen/a_weaponpieces.cpp b/src/g_hexen/a_weaponpieces.cpp index ddea93772..e6f1ff7e0 100644 --- a/src/g_hexen/a_weaponpieces.cpp +++ b/src/g_hexen/a_weaponpieces.cpp @@ -23,15 +23,7 @@ END_DEFAULTS void AFourthWeaponPiece::Serialize (FArchive &arc) { Super::Serialize (arc); - if (arc.IsStoring ()) - { - arc.UserWriteClass (FourthWeaponClass); - } - else - { - arc.UserReadClass (FourthWeaponClass); - } - arc << PieceValue << TempFourthWeapon; + arc << FourthWeaponClass << PieceValue << TempFourthWeapon; } const char *AFourthWeaponPiece::PickupMessage () diff --git a/src/g_shared/a_weaponpiece.cpp b/src/g_shared/a_weaponpiece.cpp index 6ff9bac1b..696576cf1 100644 --- a/src/g_shared/a_weaponpiece.cpp +++ b/src/g_shared/a_weaponpiece.cpp @@ -16,9 +16,7 @@ public: void Serialize (FArchive &arc) { Super::Serialize(arc); - arc << PieceMask ; - if (arc.IsStoring()) arc.UserWriteClass(PieceWeapon); - else arc.UserWriteClass(PieceWeapon); + arc << PieceMask << PieceWeapon; } }; @@ -36,9 +34,7 @@ END_DEFAULTS void AWeaponPiece::Serialize (FArchive &arc) { Super::Serialize (arc); - if (arc.IsStoring()) arc.UserWriteClass(WeaponClass); else arc.UserReadClass(WeaponClass); - arc << FullWeapon; - arc << PieceValue; + arc << WeaponClass << FullWeapon << PieceValue; } //========================================================================== diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 3e0453ccd..b5cc5bdf8 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -162,12 +162,15 @@ void cht_DoCheat (player_t *player, int cheat) break; case CHT_CHAINSAW: - type = TypeInfo::FindType ("Chainsaw"); - if (player->mo->FindInventory (type) == NULL) + if (player->mo != NULL) { - player->mo->GiveInventoryType (type); + type = TypeInfo::FindType ("Chainsaw"); + if (player->mo->FindInventory (type) == NULL) + { + player->mo->GiveInventoryType (type); + } + msg = GStrings("STSTR_CHOPPERS"); } - msg = GStrings("STSTR_CHOPPERS"); // [RH] The original cheat also set powers[pw_invulnerability] to true. // Since this is a timer and not a boolean, it effectively turned off // the invulnerability powerup, although it looks like it was meant to @@ -175,16 +178,19 @@ void cht_DoCheat (player_t *player, int cheat) break; case CHT_POWER: - item = player->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2)); - if (item != NULL) + if (player->mo != NULL) { - item->Destroy (); - msg = GStrings("TXT_CHEATPOWEROFF"); - } - else - { - player->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2)); - msg = GStrings("TXT_CHEATPOWERON"); + item = player->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2)); + if (item != NULL) + { + item->Destroy (); + msg = GStrings("TXT_CHEATPOWEROFF"); + } + else + { + player->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2)); + msg = GStrings("TXT_CHEATPOWERON"); + } } break; @@ -250,8 +256,11 @@ void cht_DoCheat (player_t *player, int cheat) break; case CHT_HEALTH: - player->health = player->mo->health = player->mo->GetDefault()->health; - msg = GStrings("TXT_CHEATHEALTH"); + if (player->mo != NULL) + { + player->health = player->mo->health = player->mo->GetDefault()->health; + msg = GStrings("TXT_CHEATHEALTH"); + } break; case CHT_KEYS: @@ -261,7 +270,7 @@ void cht_DoCheat (player_t *player, int cheat) // [GRB] case CHT_RESSURECT: - if (player->playerstate != PST_LIVE) + if (player->playerstate != PST_LIVE && player->mo != NULL) { player->playerstate = PST_LIVE; player->health = player->mo->health = player->mo->GetDefault()->health; @@ -274,7 +283,7 @@ void cht_DoCheat (player_t *player, int cheat) break; case CHT_TAKEWEAPS: - if (player->morphTics) + if (player->morphTics || player->mo != NULL) { return; } @@ -314,7 +323,7 @@ void cht_DoCheat (player_t *player, int cheat) case CHT_MDK: if (player->mo == NULL) { - Printf ("MDK won't work outside of a game.\n"); + Printf ("What do you want to kill outside of a game?\n"); } else if (!deathmatch) { @@ -456,6 +465,34 @@ void cht_Give (player_t *player, char *name, int amount) return; } + if (giveall || stricmp (name, "backpack") == 0) + { + // Select the correct type of backpack based on the game + if (gameinfo.gametype == GAME_Heretic) + { + type = TypeInfo::FindType ("BagOfHolding"); + } + else if (gameinfo.gametype == GAME_Strife) + { + type = TypeInfo::FindType ("AmmoSatchel"); + } + else if (gameinfo.gametype == GAME_Doom) + { + type = TypeInfo::FindType ("Backpack"); + } + else + { // Hexen doesn't have a backpack, foo! + type = NULL; + } + if (type != NULL) + { + GiveSpawner (player, type, 1); + } + + if (!giveall) + return; + } + if (giveall || stricmp (name, "ammo") == 0) { // Find every unique type of ammo. Give it to the player if @@ -596,23 +633,6 @@ void cht_Give (player_t *player, char *name, int amount) return; } - if (giveall || stricmp (name, "backpack") == 0) - { - // Select the correct type of backpack based on the game - if (gameinfo.gametype == GAME_Heretic) - { - name = "BagOfHolding"; - } - else if (gameinfo.gametype == GAME_Strife) - { - name = "AmmoSatchel"; - } - else if (gameinfo.gametype == GAME_Hexen && giveall) - { // Hexen doesn't have a backpack, foo! - return; - } - } - type = TypeInfo::IFindType (name); if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS(AInventory))) { diff --git a/src/m_png.cpp b/src/m_png.cpp index bf804f0e7..8bf0d0d85 100644 --- a/src/m_png.cpp +++ b/src/m_png.cpp @@ -869,6 +869,7 @@ static void UnpackPixels (int width, int bytesPerRow, int bitdepth, BYTE *row) { BYTE *out, *in; BYTE pack; + int lastbyte; out = row + width; in = row + bytesPerRow; @@ -876,6 +877,22 @@ static void UnpackPixels (int width, int bytesPerRow, int bitdepth, BYTE *row) switch (bitdepth) { case 1: + + lastbyte=width&7; + if (lastbyte!=0) + { + in--; + pack = *in; + out-=lastbyte; + out[0] = (pack >> 7) & 1; + if (lastbyte >= 2) out[1] = (pack >> 6) & 1; + if (lastbyte >= 3) out[2] = (pack >> 5) & 1; + if (lastbyte >= 4) out[3] = (pack >> 4) & 1; + if (lastbyte >= 5) out[4] = (pack >> 3) & 1; + if (lastbyte >= 6) out[5] = (pack >> 2) & 1; + if (lastbyte == 7) out[6] = (pack >> 1) & 1; + } + while (in-- > row) { pack = *in; @@ -892,6 +909,18 @@ static void UnpackPixels (int width, int bytesPerRow, int bitdepth, BYTE *row) break; case 2: + + lastbyte=width&3; + if (lastbyte!=0) + { + in--; + pack = *in; + out-=lastbyte; + out[0] = pack >> 6; + if (lastbyte >= 2) out[1] = (pack >> 4) & 3; + if (lastbyte == 3) out[2] = (pack >> 2) & 3; + } + while (in-- > row) { pack = *in; @@ -904,6 +933,15 @@ static void UnpackPixels (int width, int bytesPerRow, int bitdepth, BYTE *row) break; case 4: + lastbyte=width&1; + if (lastbyte!=0) + { + in--; + pack = *in; + out-=lastbyte; + out[0] = pack >> 4; + } + while (in-- > row) { pack = *in; diff --git a/src/name.h b/src/name.h index e9ee629fd..3909dcaae 100644 --- a/src/name.h +++ b/src/name.h @@ -34,6 +34,8 @@ public: int SetName (const char *text, bool noCreate) { return Index = FindName (text, false); } int SetName (const string &text, bool noCreate) { return Index = FindName (text.GetChars(), false); } + bool IsValidName() const { return (unsigned int)Index < NameArray.Size(); } + // Note that the comparison operators compare the names' indices, not // their text, so they cannot be used to do a lexicographical sort. bool operator == (const name &other) const { return Index == other.Index; } diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index fdcefe38f..5f91ff057 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1195,7 +1195,7 @@ bool AActor::OkayToSwitchTarget (AActor *other) if ((master != NULL && other->IsA(master->GetClass())) || // don't attack your master (or others of its type) (other->master != NULL && IsA(other->master->GetClass()))) // don't attack your minion (or those of others of your type) { - if (!P_IsHostile(this, other) && // allow target switch if other is considered hostile + if (!IsHostile (other) && // allow target switch if other is considered hostile (other->tid != TIDtoHate || TIDtoHate == 0) && // or has the tid we hate other->TIDtoHate == TIDtoHate) // or has different hate information { @@ -1205,7 +1205,7 @@ bool AActor::OkayToSwitchTarget (AActor *other) if ((other->flags3 & MF3_NOTARGET) && (other->tid != TIDtoHate || TIDtoHate == 0) && - !P_IsHostile (this, other)) + !IsHostile (other)) return false; if (threshold != 0 && !(flags4 & MF4_QUICKTORETALIATE)) return false; @@ -1214,7 +1214,7 @@ bool AActor::OkayToSwitchTarget (AActor *other) return false; } if ((gameinfo.gametype == GAME_Strife || infighting < 0) && - other->player == NULL && !P_IsHostile (this, other)) + other->player == NULL && !IsHostile (other)) { return false; // Strife & infighting off: Non-friendlies don't target other non-friendlies } diff --git a/src/p_map.cpp b/src/p_map.cpp index c7ee29718..857b78e1c 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -945,7 +945,7 @@ BOOL PIT_CheckThing (AActor *thing) } // Monsters that are clearly hostile can always hurt each other - if (!P_IsHostile(thing, tmthing->target)) + if (!thing->IsHostile (tmthing->target)) { // The same if the shooter hates the target if (thing->tid == 0 || tmthing->target->tid != thing->tid) @@ -972,7 +972,7 @@ BOOL PIT_CheckThing (AActor *thing) if (thing->GetSpecies() == tmthing->target->GetSpecies()) { // Don't hurt same species or any relative - if (!P_IsHostile(thing, tmthing->target)) + if (!thing->IsHostile (tmthing->target)) { // But only if the target isn't one's hostile. return false; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 69689a1ed..733ebe6c5 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4484,7 +4484,7 @@ bool AActor::IsFriend (AActor *other) // //========================================================================== -bool P_IsHostile (AActor *other) +bool AActor::IsHostile (AActor *other) { // Both monsters are non-friendlies so hostilities depend on infighting settings if (!((flags | other->flags) & MF_FRIENDLY)) return false; @@ -4493,8 +4493,8 @@ bool P_IsHostile (AActor *other) if (flags & other->flags & MF_FRIENDLY) { return deathmatch && - self->FriendPlayer != other->FriendPlayer && - self->FriendPlayer !=0 && + FriendPlayer != other->FriendPlayer && + FriendPlayer !=0 && other->FriendPlayer != 0; } return true; diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index a6b76c111..e74a129ad 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -125,9 +125,12 @@ void P_SetPsprite (player_t *player, int position, FState *state) // Yes, I know this is truly awful but it is the only method I can think of // that does not involve changing stuff throughout the code. // Of course this should be rewritten ASAP. - CallingState=state; + CallingState = state; // Call action routine. - state->GetAction() (player->mo); + if (player->mo != NULL) + { + state->GetAction() (player->mo); + } if (!psp->state) { break; diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index e4ebbac7c..5469f189c 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -116,13 +116,6 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) return; } -/* if (special == 52 || special == 124 || special == 51 || special == 11) - { - Printf ("Line %d has special %d (%d,%d)-(%d,%d)\n", ld-lines, special, - vertexes[mld->v1].x>>16, vertexes[mld->v1].y>>16, - vertexes[mld->v2].x>>16, vertexes[mld->v2].y>>16); - } -*/ if (tlatebase.GetMem() == NULL) { if (gameinfo.gametype == GAME_Doom) @@ -191,7 +184,7 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) ld->args[4] = tag; break; } - if (ld->flags & ML_SECRET) + if ((ld->flags & ML_SECRET) && (GET_SPAC(ld->flags) == SPAC_USE || GET_SPAC(ld->flags) == SPAC_USETHROUGH)) { ld->flags &= ~ML_MONSTERSCANACTIVATE; } diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index b0211990a..c4559e1e7 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -619,11 +619,15 @@ static void S_AddSNDINFO (int lump) Printf ("Bad ambient index (%d)\n", sc_Number); ambient = &dummy; } - else + else if (Ambients[sc_Number] == NULL) { ambient = new AmbientSound; Ambients[sc_Number] = ambient; } + else + { + ambient = Ambients[sc_Number]; + } memset (ambient, 0, sizeof(AmbientSound)); SC_MustGetString (); diff --git a/src/sdl/crashcatcher.c b/src/sdl/crashcatcher.c index 9cd338ac0..b6c1d7a84 100644 --- a/src/sdl/crashcatcher.c +++ b/src/sdl/crashcatcher.c @@ -349,11 +349,11 @@ static void crash_catcher(int signum, siginfo_t *siginfo, void *context) { char buf[256]; snprintf(buf, sizeof(buf), - "if (which gxmessage > /dev/null 2> &1);" + "if (which gxmessage > /dev/null 2>&1);" "then gxmessage -buttons \"Damn it:0\" -center -title \"Very Fatal Error\" -file %s;" - "elif (which xmessage > /dev/null 2> &1);" - "then xmessage -buttons \"Damn it:0\" -center -file %s;" - "fi", cc_logfile, cc_logfile); + "elif (which xmessage > /dev/null 2>&1);" + "then xmessage -buttons \"Damn it:0\" -center -file %s -geometry 600x400;" + "fi", cc_logfile, cc_logfile); system(buf); } #endif diff --git a/src/thingdef.cpp b/src/thingdef.cpp index 0080c1a71..27cdb8b46 100644 --- a/src/thingdef.cpp +++ b/src/thingdef.cpp @@ -282,7 +282,7 @@ static flagdef *FindFlag (flagdef *flags, int numflags, const char *flag) int lexval = stricmp (flag, flags[mid].name); if (lexval == 0) { - return &ActorFlags[mid]; + return &flags[mid]; } else if (lexval > 0) { @@ -1954,7 +1954,7 @@ void ParseActorProperties (Baggage &bag) strlwr (sc_String); propname += sc_String; } - else + else if (sc_String[0] != '-' && sc_String[1] != '+') { SC_UnGet (); } @@ -2957,7 +2957,8 @@ public: } fuglyname &operator= (const TypeInfo *foo) { - name(*this) = ENamedName(reinterpret_cast(foo)); + name *p = this; + *p = ENamedName(reinterpret_cast(foo)); return *this; } }; @@ -3299,7 +3300,7 @@ void FinishThingdef() fuglyname v; v = defaults->AmmoType1; - if (v != NAME_None) + if (v != NAME_None && v.IsValidName()) { defaults->AmmoType1 = TypeInfo::FindType(v.GetChars()); if (!defaults->AmmoType1) @@ -3313,7 +3314,7 @@ void FinishThingdef() } v = defaults->AmmoType2; - if (v != NAME_None) + if (v != NAME_None && v.IsValidName()) { defaults->AmmoType2 = TypeInfo::FindType(v.GetChars()); if (!defaults->AmmoType2) @@ -3327,7 +3328,7 @@ void FinishThingdef() } v = defaults->SisterWeaponType; - if (v != NAME_None) + if (v != NAME_None && v.IsValidName()) { defaults->SisterWeaponType = TypeInfo::FindType(v.GetChars()); if (!defaults->SisterWeaponType) @@ -3373,5 +3374,3 @@ void FinishThingdef() } } } - -