From 25f90d62212b56a30a9ea0bc11be59bb45a75769 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Apr 2006 16:27:41 +0000 Subject: [PATCH] SVN r27 (trunk) --- docs/rh-log.txt | 94 +++++++++++++++++++ src/actor.h | 3 + src/am_map.cpp | 88 ++++++++++++++++-- src/c_bind.cpp | 11 +++ src/d_dehacked.cpp | 41 ++++++++- src/d_dehacked.h | 1 + src/d_main.cpp | 2 + src/d_net.cpp | 2 +- src/d_player.h | 7 ++ src/doomdef.h | 3 +- src/files.cpp | 49 +++++++++- src/files.h | 28 +++++- src/g_game.cpp | 46 +++++++++- src/g_hexen/a_centaur.cpp | 1 + src/g_hexen/a_demons.cpp | 2 + src/g_hexen/a_ettin.cpp | 1 + src/g_hexen/a_pig.cpp | 2 +- src/g_hub.cpp | 151 +++++++++++++++++++++++++++++++ src/g_hub.h | 14 +++ src/g_level.cpp | 48 ++++++++-- src/g_level.h | 9 +- src/g_raven/a_artiegg.cpp | 5 +- src/g_shared/a_action.cpp | 4 +- src/g_shared/a_artifacts.cpp | 5 +- src/g_shared/a_hatetarget.cpp | 2 +- src/g_shared/a_movingcamera.cpp | 4 + src/g_shared/a_pickups.cpp | 31 ++----- src/g_shared/a_pickups.h | 2 +- src/g_shared/a_sharedmisc.cpp | 1 + src/g_shared/a_weapons.cpp | 5 +- src/g_shared/sbar.h | 5 +- src/g_shared/shared_sbar.cpp | 11 ++- src/g_strife/a_acolyte.cpp | 1 + src/g_strife/a_macil.cpp | 7 +- src/g_strife/a_oracle.cpp | 2 +- src/g_strife/a_strifeweapons.cpp | 20 +++- src/gameconfigfile.cpp | 6 +- src/info.h | 4 +- src/infodefaults.cpp | 4 +- src/infomacros.h | 4 +- src/m_cheat.cpp | 5 +- src/m_menu.cpp | 8 +- src/m_misc.cpp | 3 +- src/m_options.cpp | 35 ++++++- src/p_conversation.cpp | 29 ++++-- src/p_doors.cpp | 6 -- src/p_enemy.cpp | 26 ++++-- src/p_floor.cpp | 17 +++- src/p_interaction.cpp | 6 +- src/p_lnspec.h | 1 + src/p_local.h | 1 - src/p_mobj.cpp | 69 ++++++-------- src/p_saveg.cpp | 3 +- src/p_setup.cpp | 1 + src/p_spec.cpp | 128 ++++++++++++++++++++++---- src/p_tick.cpp | 1 + src/p_user.cpp | 31 ++++--- src/po_man.cpp | 6 +- src/r_data.cpp | 41 ++++++--- src/r_defs.h | 3 + src/r_main.cpp | 6 +- src/r_main.h | 2 +- src/r_segs.cpp | 16 +++- src/s_advsound.cpp | 63 +++++++++++++ src/s_sndseq.cpp | 24 ++++- src/s_sndseq.h | 4 +- src/s_sound.cpp | 65 ++++++++++++- src/thingdef.cpp | 14 +++ src/v_font.cpp | 6 +- src/v_video.h | 2 +- src/version.h | 8 +- src/win32/i_input.cpp | 4 +- wadsrc/languages/french.txt | 2 +- zdoom.vcproj | 6 ++ 74 files changed, 1133 insertions(+), 235 deletions(-) create mode 100644 src/g_hub.cpp create mode 100644 src/g_hub.h diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 3202375b3..6149983a8 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,98 @@ April 11, 2006 (Changes by Graf Zahl) +- Fixed: Strife's dialogs don't give weapons to the player he already has. +- Fixed: The INDIANA cheat in Hexen gives 25 of each item, not just 1. +- Fixed: The stair builder's compatibility mode must do a linear search + for sectors. Searching the hasch chain doesn't work here. +- Fixed: Any monster with a TakeSpecialDamage method should call the + super class's method instead of simply returning the damage amount. +- Fixed: Hexen's mash monsters cannot be frozen. No matter how you kill + them they just vanish. This means they need the NOICEDEATH flag. +- Fixed: Morphing a monster must also copy its translucency settings. +- Fixed: The first Macil must react to weapon fire, even though he + doesn't get hurt by it. +- Fixed: Anything with a raise state needs the MF_CORPSE flag when dying + because otherwise it can't be revived. +- Fixed: Player names in Heretic, Hexen nand Strife could only be 13 + characters because the input routine did an unnecessary font size check. +- Added: After saving the game the savegame should be checked + and in case of an error an appropriate message be output. +- Fixed: The pig player had an initial health of 100, not 30. +- Fixed: Morphing a player removes the armor after transferring the + inventory to the morphed version - but it tried to remove it from the + unmorphed player instead. +- Fixed: Heretic uses Backspace to activate the Tome of Power by default. +- Fixed: 'Use all' should not try to use puzzle items. +- Made FileReader's methods virtual. Right now this isn't important + but when ZIP support will be added it is needed. Also added a + MemoryReader class that derives from FileReader. +- Added a pointer check to DI_Acquire and DI_Unacquire. GZDoom definitely + had problems with that so it might be a good idea to always check these + pointers. +- Added an engine signature to the savegame. The inability to distinguish + between ZDoom and GZDoom savegames constantly forced me to use some ugly + tricks which broke the versioning system. This may also be useful for + other derivates that have to save additional data in a savegame. +- Due to the savegame version bump I removed all compatibility code. +- I had to bump the minimum savegame version because I got some strange + effects with old savegames. On the positive side, this allows me to + do a few more radical changes to the savegame code. ;) +- Fixed: CanvasTextures weren't saved in a savegame. +- Fixed: Multiple warp commands for the same texture were cumulative. +- Changed FPatchTexture::MakeTexture and FIMGZTexture::MakeTexture so they + don't re-initialize the texture's size information repeatedly. This can + cause problems if code was added that manipulates these values after loading + the textures. +- Changed FPatchTexture::GetDimensions to use ReopenLumpNum instead of + OpenLumpNum. Once ZIP handling is added the current code won't work anymore + without adding a highly expensive copy operator to FWadLump. +- Added Transfer_WallLight special. This is similar to Transfer_Floor/Ceilinglight + but affects walls instead. +- Fixed: P_TestActivateLine must check whether a valid actor is trying + to activate the line. +- Added a check for MF2_NOTELEPORT to the special activation check for + Booms generic triggers. This excludes most items from activating these + lines that are not supposed to do that. +- Added a sv_dropstyle CVAR so that the way items are dropped is no longer + dependent on the game being played. +- Added MF4_FRIGHTENED flag from .96x. +- Added a CVAR that disables the automap background graphic in Heretic + and Hexen. +- Added more color options to the automap, including the option to show + secrets. +- Added menu option for the monster movement interpolation CVAR. +- Fixed: Strife's grenades don't make bouncing sounds. +- Fixed: Strife's grenades lose 50% of their momentum when bouncing, + not 30% like in Hexen. +- Fixed: HexenHack must be reset for each MAPINFO lump being parsed. +- Turned monster falling damage into a level flag so that it can be + used in all games, not just Hexen. +- Added the map's lump name to the savegame information. This is useful + for those who remember maps by their lump name and not the description. +- Added a total game time counter and made the total time display on + the intermission screen operrable. Also added an optional total time + display for the automap. +- Added support for full hub intermission statistics. To make this work + properly level.time is now being reset after changing hubs. +- Added GZDoom's local SNDINFO/SNDSEQ code. This was supposed to be in + .96x but that was cancelled before I had the chance. +- Made DCanvas::FlatFill virtual so it can be overridden by other + types of canvases (e.g. OpenGL.) +- Fixed: CR_UNTRANSLATED was uninitialized for FON2 fonts +- Fixed: Hexen uses a view height of 48, not 41. +- Changed: Multiplayer weapons will be spawned in coop games now + unless the player explicitly disables this. There are many WADs + out there that need the additional weapons in coop games. +- Added code that remaps MF_NOSECTOR to RF_INVISIBLE for all items + touched by Dehacked and for ABossEye. MF_NOSECTOR makes any + item completely deaf so it is very dangerous to use with monsters + or other things that depend on their sound target. +- Fixed: The Dehacked code cleared one of the translation flags. +- Fixed: The dehacked parser must set EnglishStrings to NULL after + freeing the memory. +- Copied a fix for restoring the weapon slots from 2.1.0. +- Fixed: APathFollower::Interpolate needs some NULL pointer checks. +- Added MF2_NOTELEPORT to ABlood and AIceChunk. Teleporting blood can + seriously mess up one-time teleporters - plus it looks just weird. - Fixed: It was possible to use things through closed walls when the wall was further away than 64 map units. - Added a check for MF3_BLOODLESSIMPACT to P_LineAttack so that bloodless diff --git a/src/actor.h b/src/actor.h index 6dfd3f447..a7a435b7f 100644 --- a/src/actor.h +++ b/src/actor.h @@ -270,6 +270,8 @@ enum MF4_ALLOWPARTICLES = 0x08000000, // this puff type can be replaced by particles MF4_NOEXTREMEDEATH = 0x10000000, // this projectile or weapon never gibs its victim MF4_EXTREMEDEATH = 0x20000000, // this projectile or weapon always gibs its victim + MF4_FRIGHTENED = 0x40000000, // Monster runs away from player + MF4_NOBOUNCESOUND = 0x80000000, // Strife's grenades don't make a bouncing sound. // --- mobj.renderflags --- @@ -633,6 +635,7 @@ public: BYTE MinMissileChance;// [RH] If a random # is > than this, then missile attack. WORD SpawnFlags; fixed_t meleerange; + fixed_t bouncefactor; // Strife's grenades use 50%, Hexen's Flechettes 70. // a linked list of sectors where this object appears struct msecnode_s *touching_sectorlist; // phares 3/14/98 diff --git a/src/am_map.cpp b/src/am_map.cpp index f8797d8ff..ecc1821fd 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -53,11 +53,13 @@ static int Background, YourColor, WallColor, TSWallColor, FDWallColor, CDWallColor, ThingColor, + ThingColor_Item, ThingColor_Monster, ThingColor_Friend, SecretWallColor, GridColor, XHairColor, NotSeenColor, LockedColor, AlmostBackground, - IntraTeleportColor, InterTeleportColor; + IntraTeleportColor, InterTeleportColor, + SecretSectorColor; static int DoomColors[11]; static byte DoomPaletteVals[11*3] = @@ -100,6 +102,7 @@ CVAR (Bool, am_showsecrets, true, CVAR_ARCHIVE); CVAR (Bool, am_showmonsters, true, CVAR_ARCHIVE); CVAR (Bool, am_showitems, false, CVAR_ARCHIVE); CVAR (Bool, am_showtime, true, CVAR_ARCHIVE); +CVAR (Bool, am_showtotaltime, false, CVAR_ARCHIVE); CVAR (Bool, am_usecustomcolors, true, CVAR_ARCHIVE); CVAR (Float, am_ovtrans, 1.f, CVAR_ARCHIVE); CVAR (Color, am_backcolor, 0x6c5440, CVAR_ARCHIVE); @@ -122,6 +125,15 @@ CVAR (Color, am_ovunseencolor, 0x00226e, CVAR_ARCHIVE); CVAR (Color, am_ovtelecolor, 0xffff00, CVAR_ARCHIVE); CVAR (Color, am_intralevelcolor, 0x0000ff, CVAR_ARCHIVE); CVAR (Color, am_interlevelcolor, 0xff0000, CVAR_ARCHIVE); +CVAR (Color, am_secretsectorcolor, 0xff00ff, CVAR_ARCHIVE); +CVAR (Int, am_map_secrets, 1, CVAR_ARCHIVE); +CVAR (Bool, am_drawmapback, true, CVAR_ARCHIVE); +CVAR (Color, am_thingcolor_friend, 0xfcfcfc, CVAR_ARCHIVE); +CVAR (Color, am_thingcolor_monster, 0xfcfcfc, CVAR_ARCHIVE); +CVAR (Color, am_thingcolor_item, 0xfcfcfc, CVAR_ARCHIVE); +CVAR (Color, am_ovthingcolor_friend, 0xe88800, CVAR_ARCHIVE); +CVAR (Color, am_ovthingcolor_monster, 0xe88800, CVAR_ARCHIVE); +CVAR (Color, am_ovthingcolor_item, 0xe88800, CVAR_ARCHIVE); // drawing stuff #define AM_PANDOWNKEY KEY_DOWNARROW @@ -370,6 +382,11 @@ void AM_getIslope (mline_t *ml, islope_t *is) } */ +void AM_GetPosition(fixed_t & x, fixed_t & y) +{ + x = (m_x + m_w/2) << FRACTOMAPBITS; + y = (m_y + m_h/2) << FRACTOMAPBITS; +} // // // @@ -635,7 +652,10 @@ static void AM_initColors (BOOL overlayed) if (overlayed) { YourColor = am_ovyourcolor.GetIndex (); - SecretWallColor = WallColor = am_ovwallcolor.GetIndex (); + SecretSectorColor = SecretWallColor = WallColor = am_ovwallcolor.GetIndex (); + ThingColor_Item = am_ovthingcolor_item.GetIndex(); + ThingColor_Friend = am_ovthingcolor_friend.GetIndex(); + ThingColor_Monster = am_ovthingcolor_monster.GetIndex(); ThingColor = am_ovthingcolor.GetIndex (); FDWallColor = CDWallColor = LockedColor = am_ovotherwallscolor.GetIndex (); NotSeenColor = TSWallColor = am_ovunseencolor.GetIndex (); @@ -651,6 +671,9 @@ static void AM_initColors (BOOL overlayed) TSWallColor = am_tswallcolor.GetIndex (); FDWallColor = am_fdwallcolor.GetIndex (); CDWallColor = am_cdwallcolor.GetIndex (); + ThingColor_Item = am_thingcolor_item.GetIndex(); + ThingColor_Friend = am_thingcolor_friend.GetIndex(); + ThingColor_Monster = am_thingcolor_monster.GetIndex(); ThingColor = am_thingcolor.GetIndex (); GridColor = am_gridcolor.GetIndex (); XHairColor = am_xhaircolor.GetIndex (); @@ -658,6 +681,7 @@ static void AM_initColors (BOOL overlayed) LockedColor = am_lockedcolor.GetIndex (); InterTeleportColor = am_interlevelcolor.GetIndex (); IntraTeleportColor = am_intralevelcolor.GetIndex (); + SecretSectorColor = am_secretsectorcolor.GetIndex (); DWORD ba = am_backcolor; @@ -679,13 +703,17 @@ static void AM_initColors (BOOL overlayed) Background = DoomColors[0]; YourColor = DoomColors[1]; AlmostBackground = DoomColors[2]; - SecretWallColor = + SecretSectorColor = + SecretWallColor = WallColor = DoomColors[3]; TSWallColor = DoomColors[4]; FDWallColor = DoomColors[5]; LockedColor = CDWallColor = DoomColors[6]; - ThingColor = DoomColors[7]; + ThingColor_Item = + ThingColor_Friend = + ThingColor_Monster = + ThingColor = DoomColors[7]; GridColor = DoomColors[8]; XHairColor = DoomColors[9]; NotSeenColor = DoomColors[10]; @@ -1079,7 +1107,7 @@ void AM_Ticker () // void AM_clearFB (int color) { - if (mapback == NULL) + if (mapback == NULL || !am_drawmapback) { screen->Clear (0, 0, f_w, f_h, color); } @@ -1798,9 +1826,19 @@ void AM_drawWalls (bool allmap) { if ((lines[i].flags & ML_DONTDRAW) && am_cheat == 0) continue; + if (!lines[i].backsector) { - AM_drawMline(&l, WallColor); + if (lines[i].frontsector->oldspecial && + (am_map_secrets==2 || (am_map_secrets==1 && !(lines[i].frontsector->special&SECRET_MASK)))) + { + // map secret sectors like Boom + AM_drawMline(&l, SecretSectorColor); + } + else + { + AM_drawMline(&l, WallColor); + } } else { @@ -1828,9 +1866,30 @@ void AM_drawWalls (bool allmap) AM_drawMline(&l, WallColor); } else if (lines[i].special == Door_LockedRaise || - lines[i].special == ACS_LockedExecute) + lines[i].special == ACS_LockedExecute || + (lines[i].special == Generic_Door && lines[i].args[4]!=0)) { - AM_drawMline (&l, LockedColor); // locked special + if (am_usecustomcolors) + { + int P_GetMapColorForLock(int lock); + int lock; + + + if (lines[i].special==Door_LockedRaise) lock=lines[i].args[3]; + else lock=lines[i].args[4]; + + int color = P_GetMapColorForLock(lock); + + if (color > 0) + { + color = ColorMatcher.Pick(RPART(color), GPART(color), BPART(color)); + } + else color = LockedColor; + + AM_drawMline (&l, color); + } + else + AM_drawMline (&l, LockedColor); // locked special } else if (lines[i].backsector->floorplane != lines[i].frontsector->floorplane) @@ -2001,8 +2060,9 @@ void AM_drawPlayers () } } -void AM_drawThings (int color) +void AM_drawThings (int _color) { + int color; int i; AActor* t; mpoint_t p; @@ -2023,6 +2083,16 @@ void AM_drawThings (int color) angle += ANG90 - players[consoleplayer].camera->angle; } + color = ThingColor; + + // use separate colors for special thing types + if (t->flags3&MF3_ISMONSTER && !(t->flags&MF_CORPSE)) + { + if (t->flags & MF_FRIENDLY || !(t->flags & MF_COUNTKILL)) color = ThingColor_Friend; + else color = ThingColor_Monster; + } + else if (t->flags&MF_SPECIAL) color = ThingColor_Item; + AM_drawLineCharacter (thintriangle_guy, NUMTHINTRIANGLEGUYLINES, 16<ActorInfo!=NULL && !ti->IsDescendantOf(RUNTIME_CLASS(ATeleportDest))) + { + AActor * def = GetDefaultByType(ti); + + if (def->flags&MF_NOSECTOR) + { + def->flags&=~MF_NOSECTOR; + def->renderflags|=RF_INVISIBLE; + } + } + } + // The BossEye must be handled even without any Dehacked interference + // because otherwise it would not react to sound. + const TypeInfo * ti = TypeInfo::FindType("BossEye"); + if (ti!=NULL) + { + AActor * def = GetDefaultByType(ti); + + if (def->flags&MF_NOSECTOR) + { + def->flags&=~MF_NOSECTOR; + def->renderflags|=RF_INVISIBLE; + } + } +} + void A_SpawnDehackedPickup (AActor *actor) { if ((size_t)actor->health < DehackedPickups.Size()) diff --git a/src/d_dehacked.h b/src/d_dehacked.h index eec8fc2e6..af83ba87d 100644 --- a/src/d_dehacked.h +++ b/src/d_dehacked.h @@ -36,5 +36,6 @@ void DoDehPatch (const char *patchfile, BOOL autoloading); void FinishDehPatch (); +void HandleNoSector(); #endif //__D_DEHACK_H__ diff --git a/src/d_main.cpp b/src/d_main.cpp index ab1ede81e..1aec850a2 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -355,6 +355,7 @@ CVAR (Flag, sv_nojump, dmflags, DF_NO_JUMP); CVAR (Flag, sv_nofreelook, dmflags, DF_NO_FREELOOK); CVAR (Flag, sv_respawnsuper, dmflags, DF_RESPAWN_SUPER); CVAR (Flag, sv_nofov, dmflags, DF_NO_FOV); +CVAR (Flag, sv_noweaponspawn, dmflags, DF_NO_COOP_WEAPON_SPAWN); //========================================================================== // @@ -2048,6 +2049,7 @@ void D_DoomMain (void) DoDehPatch (NULL, true); // See if there's a patch in a PWAD FinishDehPatch (); // Create replacements for dehacked pickups } + HandleNoSector (); // clear NOSECTOR flag off all actors modified by Dehacked and the BossEye. FActorInfo::StaticSetActorNums (); diff --git a/src/d_net.cpp b/src/d_net.cpp index 53f4c671c..c9e293816 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2060,7 +2060,7 @@ void Net_DoCommand (int type, byte **stream, int player) while (item != NULL) { AInventory *next = item->Inventory; - if (item->ItemFlags & IF_INVBAR) + if (item->ItemFlags & IF_INVBAR && !(item->IsKindOf(RUNTIME_CLASS(APuzzleItem)))) { players[player].mo->UseInventory (item); } diff --git a/src/d_player.h b/src/d_player.h index 65f331e99..21a52c50e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -170,6 +170,7 @@ public: float FOV; // current field of vision fixed_t viewz; // focal origin above r.z fixed_t viewheight; // base height above floor for viewz + fixed_t defaultviewheight; // The normal view height when standing fixed_t deltaviewheight; // squat speed. fixed_t bob; // bounded/scaled total momentum @@ -275,6 +276,12 @@ public: float BlendA; char *LogText; // [RH] Log for Strife + + + fixed_t GetDeltaViewHeight() const + { + return (defaultviewheight - viewheight) >> 3; + } }; typedef player_s player_t; diff --git a/src/doomdef.h b/src/doomdef.h index 449004da3..2f454cb7f 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -219,6 +219,7 @@ enum DF_NO_FREELOOK = 1 << 17, // Don't allow freelook DF_RESPAWN_SUPER = 1 << 18, // Respawn invulnerability and invisibility DF_NO_FOV = 1 << 19, // Only let the arbitrator set FOV (for all players) + DF_NO_COOP_WEAPON_SPAWN = 1 << 20, // Don't spawn multiplayer weapons in coop games }; // [BC] More dmflags. w00p! @@ -260,7 +261,7 @@ enum COMPATF_NOTOSSDROPS = 1 << 7, // Spawn dropped items directly on the floor? COMPATF_USEBLOCKING = 1 << 8, // Any special line can block a use line COMPATF_NODOORLIGHT = 1 << 9, // Don't do the BOOM local door light effect - COMPATF_RAVENSCROLL = 1 << 10, // Raven's scrollers user their original carrying speed + COMPATF_RAVENSCROLL = 1 << 10, // Raven's scrollers use their original carrying speed }; // phares 3/20/98: diff --git a/src/files.cpp b/src/files.cpp index 191787fc7..dede449d6 100644 --- a/src/files.cpp +++ b/src/files.cpp @@ -1,5 +1,6 @@ #include "files.h" #include "i_system.h" +#include "templates.h" FileReader::FileReader () : File(NULL), Length(0), CloseOnDestruct(false) @@ -100,7 +101,7 @@ long FileReader::CalcFileLen() const // Now for the zlib wrapper ------------------------------------------------- -FileReaderZ::FileReaderZ (FileReader &file) +FileReaderZ::FileReaderZ (FileReader &file, bool zip) : File(file), SawEOF(false) { int err; @@ -110,7 +111,9 @@ FileReaderZ::FileReaderZ (FileReader &file) Stream.zalloc = Z_NULL; Stream.zfree = Z_NULL; - err = inflateInit (&Stream); + if (!zip) err = inflateInit (&Stream); + else err = inflateInit2 (&Stream, -MAX_WBITS); + if (err != Z_OK) { I_Error ("FileReaderZ: inflateInit failed: %d\n", err); @@ -162,3 +165,45 @@ void FileReaderZ::FillBuffer () Stream.next_in = InBuff; Stream.avail_in = numread; } + +MemoryReader::MemoryReader (const char *buffer, long length) +{ + bufptr=buffer; + Length=length; + FilePos=0; +} + +MemoryReader::~MemoryReader () +{ +} + +long MemoryReader::Tell () const +{ + return FilePos; +} + +long MemoryReader::Seek (long offset, int origin) +{ + switch (origin) + { + case SEEK_CUR: + offset+=FilePos; + break; + + case SEEK_END: + offset+=Length; + break; + + } + FilePos=clamp(offset,0,Length-1); + return 0; +} + +long MemoryReader::Read (void *buffer, long len) +{ + if (len>Length-FilePos) len=Length-FilePos; + if (len<0) len=0; + memcpy(buffer,bufptr+FilePos,len); + FilePos+=len; + return len; +} diff --git a/src/files.h b/src/files.h index 1cbd56805..099a0c1ef 100644 --- a/src/files.h +++ b/src/files.h @@ -12,11 +12,11 @@ public: FileReader (const char *filename); FileReader (FILE *file); FileReader (FILE *file, long length); - ~FileReader (); + virtual ~FileReader (); - long Tell () const; - long Seek (long offset, int origin); - long Read (void *buffer, long len); + virtual long Tell () const; + virtual long Seek (long offset, int origin); + virtual long Read (void *buffer, long len); long GetLength () const { return Length; } // If you use the underlying FILE without going through this class, @@ -69,6 +69,7 @@ protected: private: long CalcFileLen () const; +protected: bool CloseOnDestruct; }; @@ -76,7 +77,7 @@ private: class FileReaderZ { public: - FileReaderZ (FileReader &file); + FileReaderZ (FileReader &file, bool zip=false); ~FileReaderZ (); long Read (void *buffer, long len); @@ -132,4 +133,21 @@ private: void FillBuffer (); }; + +class MemoryReader : public FileReader +{ +public: + MemoryReader (const char *buffer, long length); + ~MemoryReader (); + + virtual long Tell () const; + virtual long Seek (long offset, int origin); + virtual long Read (void *buffer, long len); + +protected: + const char * bufptr; +}; + + + #endif diff --git a/src/g_game.cpp b/src/g_game.cpp index b1de03942..1cd5e8cc5 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -75,6 +75,9 @@ #include +#include "g_hub.h" + + static FRandom pr_dmspawn ("DMSpawn"); const int SAVEPICWIDTH = 216; @@ -1607,6 +1610,21 @@ void G_DoLoadGame () SaveVersion = 0; + // Check whether this savegame actually has been created by a compatible engine. + // Since there are ZDoom derivates using the exact same savegame format but + // with mutual incompatibilities this check simplifies things significantly. + char * engine = M_GetPNGText (png, "Engine"); + if (engine == NULL || 0 != strcmp (engine, GAMESIG)) + { + // Make a special case for the message printed for old savegames that don't + // have this information. + if (engine == NULL) Printf ("Savegame is from an incompatible version\n"); + else Printf ("Savegame is from another ZDoom based engine\n"); + delete png; + fclose (stdfile); + return; + } + if (!M_GetPNGText (png, "ZDoom Save Version", sigcheck, 16) || 0 != strncmp (sigcheck, SAVESIG, 9) || // ZDOOMSAVE is the first 9 chars (SaveVersion = atoi (sigcheck+9)) < MINSAVEVER) @@ -1631,6 +1649,9 @@ void G_DoLoadGame () return; } + // Read intermission data for hubs + G_ReadHubInfo(png); + bglobal.RemoveAllBots (true); text = M_GetPNGText (png, "Important CVARs"); @@ -1642,7 +1663,7 @@ void G_DoLoadGame () } // dearchive all the modifications - if (M_FindPNGChunk (png, MAKE_ID('p','t','I','c') == 8)) + if (M_FindPNGChunk (png, MAKE_ID('p','t','I','c')) == 8) { DWORD time[2]; fread (&time, 8, 1, stdfile); @@ -1825,7 +1846,8 @@ static void PutSaveComment (FILE *file) M_AppendPNGText (file, "Creation Time", comment); // Get level name - strcpy (comment, level.level_name); + //strcpy (comment, level.level_name); + sprintf(comment, "%s - %s", level.mapname, level.level_name); len = (WORD)strlen (comment); comment[len] = '\n'; @@ -1944,12 +1966,16 @@ void G_DoSaveGame (bool okForQuicksave) SaveVersion = SAVEVER; PutSavePic (stdfile, SAVEPICWIDTH, SAVEPICHEIGHT); M_AppendPNGText (stdfile, "Software", "ZDoom " DOTVERSIONSTR); + M_AppendPNGText (stdfile, "Engine", GAMESIG); M_AppendPNGText (stdfile, "ZDoom Save Version", SAVESIG); M_AppendPNGText (stdfile, "Title", savedescription); M_AppendPNGText (stdfile, "Current Map", level.mapname); PutSaveWads (stdfile); PutSaveComment (stdfile); + // Intermission stats for hubs + G_WriteHubInfo(stdfile); + { byte vars[4096], *vars_p; vars_p = vars; @@ -1986,7 +2012,21 @@ void G_DoSaveGame (bool okForQuicksave) M_FinishPNG (stdfile); fclose (stdfile); - Printf ("%s\n", GStrings("GGSAVED")); + // Check whether the file is ok. + bool success = false; + stdfile = fopen (savegamefile.GetChars(), "rb"); + if (stdfile != NULL) + { + PNGHandle * pngh = M_VerifyPNG(stdfile); + if (pngh != NULL) + { + success=true; + delete pngh; + } + fclose(stdfile); + } + if (success) Printf ("%s\n", GStrings("GGSAVED")); + else Printf(PRINT_HIGH, "Save failed\n"); BackupSaveName = savegamefile; savegamefile = ""; diff --git a/src/g_hexen/a_centaur.cpp b/src/g_hexen/a_centaur.cpp index ce49773f8..83054379d 100644 --- a/src/g_hexen/a_centaur.cpp +++ b/src/g_hexen/a_centaur.cpp @@ -145,6 +145,7 @@ IMPLEMENT_STATELESS_ACTOR (ACentaurMash, Hexen, -1, 103) PROP_FlagsSet (MF_NOBLOOD) PROP_Flags2Set (MF2_BLASTED) PROP_Flags2Clear (MF2_TELESTOMP) + PROP_Flags4Set(MF4_NOICEDEATH) PROP_RenderStyle (STYLE_Translucent) PROP_Alpha (HX_ALTSHADOW) diff --git a/src/g_hexen/a_demons.cpp b/src/g_hexen/a_demons.cpp index 57eb83948..f833f1ac5 100644 --- a/src/g_hexen/a_demons.cpp +++ b/src/g_hexen/a_demons.cpp @@ -118,6 +118,7 @@ IMPLEMENT_STATELESS_ACTOR (ADemon1Mash, Hexen, -1, 100) PROP_FlagsSet (MF_NOBLOOD) PROP_Flags2Set (MF2_BLASTED) PROP_Flags2Clear (MF2_TELESTOMP) + PROP_Flags4Set(MF4_NOICEDEATH) PROP_RenderStyle (STYLE_Translucent) PROP_Alpha (HX_ALTSHADOW) @@ -373,6 +374,7 @@ IMPLEMENT_STATELESS_ACTOR (ADemon2Mash, Hexen, -1, 101) PROP_FlagsSet (MF_NOBLOOD) PROP_Flags2Set (MF2_BLASTED) PROP_Flags2Clear (MF2_TELESTOMP) + PROP_Flags4Set(MF4_NOICEDEATH) PROP_RenderStyle (STYLE_Translucent) PROP_Alpha (HX_ALTSHADOW) diff --git a/src/g_hexen/a_ettin.cpp b/src/g_hexen/a_ettin.cpp index d66c34e3d..063cc2be9 100644 --- a/src/g_hexen/a_ettin.cpp +++ b/src/g_hexen/a_ettin.cpp @@ -144,6 +144,7 @@ class AEttinMash : public AEttin IMPLEMENT_STATELESS_ACTOR (AEttinMash, Hexen, -1, 102) PROP_FlagsSet (MF_NOBLOOD) PROP_Flags2Set (MF2_FLOORCLIP|MF2_PASSMOBJ|MF2_MCROSS|MF2_PUSHWALL|MF2_BLASTED) + PROP_Flags4Set(MF4_NOICEDEATH) PROP_RenderStyle (STYLE_Translucent) PROP_Alpha (HX_ALTSHADOW) diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index 8c58c656c..ce961f15f 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -130,7 +130,7 @@ FState APigPlayer::States[] = }; IMPLEMENT_ACTOR (APigPlayer, Hexen, -1, 0) - PROP_SpawnHealth (100) + PROP_SpawnHealth (30) PROP_ReactionTime (0) PROP_PainChance (255) PROP_RadiusFixed (16) diff --git a/src/g_hub.cpp b/src/g_hub.cpp new file mode 100644 index 000000000..65551fdc3 --- /dev/null +++ b/src/g_hub.cpp @@ -0,0 +1,151 @@ +/* +** g_hub.cpp +** +** Intermission stats for hubs +** +**--------------------------------------------------------------------------- +** Copyright 2005 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "doomstat.h" +#include "g_hub.h" +#include "tarray.h" +#include "g_level.h" +#include "g_game.h" +#include "gi.h" +#include "files.h" +#include "m_png.h" + + +//========================================================================== +// +// Player is leaving the current level +// +//========================================================================== + +TArray hubdata; + +void G_LeavingHub(int mode, cluster_info_t * cluster, wbstartstruct_t * wbs) +{ + unsigned int i,j; + + if (cluster->flags & CLUSTER_HUB) + { + for(i=0;imaxkills=wbs->maxitems=wbs->maxsecret=0; + for(i=0;iplyr[i].sitems=wbs->plyr[i].skills=wbs->plyr[i].ssecret=0; + } + + for(i=0;imaxkills += hubdata[i].maxkills; + wbs->maxitems += hubdata[i].maxitems; + wbs->maxsecret += hubdata[i].maxsecret; + for(j=0;jplyr[j].sitems += hubdata[i].plyr[j].sitems; + wbs->plyr[j].skills += hubdata[i].plyr[j].skills; + wbs->plyr[j].ssecret += hubdata[i].plyr[j].ssecret; + } + } + if (cluster->clustername) + { + strncpy(level.level_name, cluster->clustername, 64); + level.level_name[63]=0; + } + } + } + if (mode!=FINISH_SameHub) hubdata.Clear(); +} + +//========================================================================== +// +// Serialize intermission info for hubs +// +//========================================================================== +#define HUBS_ID MAKE_ID('h','u','B','s') + +static void G_SerializeHub(FArchive & arc) +{ + int i=hubdata.Size(); + arc << i; + if (i>0) + { + if (arc.IsStoring()) arc.Write(&hubdata[0], i * sizeof(wbstartstruct_t)); + else + { + hubdata.Resize(i); + arc.Read(&hubdata[0], i * sizeof(wbstartstruct_t)); + } + } + else hubdata.Clear(); +} + +void G_WriteHubInfo (FILE *file) +{ + FPNGChunkArchive arc(file, HUBS_ID); + G_SerializeHub(arc); +} + +void G_ReadHubInfo (PNGHandle *png) +{ + int chunklen; + + if ((chunklen = M_FindPNGChunk (png, HUBS_ID)) != 0) + { + FPNGChunkArchive arc (png->File->GetFile(), HUBS_ID, chunklen); + G_SerializeHub(arc); + } +} diff --git a/src/g_hub.h b/src/g_hub.h new file mode 100644 index 000000000..8a7355f8b --- /dev/null +++ b/src/g_hub.h @@ -0,0 +1,14 @@ +#ifndef __G_HUB_H +#define __G_HUB_H + +#include +//#include +#include "g_level.h" +#include "wi_stuff.h" + +void G_WriteHubInfo (FILE *file); +void G_ReadHubInfo (PNGHandle *png); +void G_LeavingHub(int mode, cluster_info_t * cluster, struct wbstartstruct_s * wbs); + +#endif + diff --git a/src/g_level.cpp b/src/g_level.cpp index 9214857c9..5952677be 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -74,6 +74,7 @@ #include "gi.h" +#include "g_hub.h" EXTERN_CVAR (Float, sv_gravity) EXTERN_CVAR (Float, sv_aircontrol) @@ -234,6 +235,11 @@ static const char *MapInfoMapLevel[] = "airsupply", "specialaction", "keepfullinventory", + "monsterfallingdamage", + "nomonsterfallingdamage", + "sndseq", + "sndinfo", + "soundinfo", NULL }; @@ -340,6 +346,11 @@ MapHandlers[] = { MITYPE_INT, lioffset(airsupply), 0 }, { MITYPE_SPECIALACTION, lioffset(specialactions), 0 }, { MITYPE_SETFLAG, LEVEL_KEEPFULLINVENTORY, 0 }, + { MITYPE_SETFLAG, LEVEL_MONSTERFALLINGDAMAGE, 0 }, + { MITYPE_CLRFLAG, LEVEL_MONSTERFALLINGDAMAGE, 0 }, + { MITYPE_LUMPNAME, lioffset(sndseq), 0 }, + { MITYPE_LUMPNAME, lioffset(soundinfo), 0 }, + { MITYPE_LUMPNAME, lioffset(soundinfo), 0 }, }; static const char *MapInfoClusterLevel[] = @@ -354,6 +365,7 @@ static const char *MapInfoClusterLevel[] = "cdid", "entertextislump", "exittextislump", + "name", NULL }; @@ -368,7 +380,8 @@ MapInfoHandler ClusterHandlers[] = { MITYPE_INT, cioffset(cdtrack), 0 }, { MITYPE_HEX, cioffset(cdid), 0 }, { MITYPE_SETFLAG, CLUSTER_ENTERTEXTINLUMP, 0 }, - { MITYPE_SETFLAG, CLUSTER_EXITTEXTINLUMP, 0 } + { MITYPE_SETFLAG, CLUSTER_EXITTEXTINLUMP, 0 }, + { MITYPE_STRING, cioffset(clustername), 0 }, }; static void ParseMapInfoLower (MapInfoHandler *handlers, @@ -414,6 +427,10 @@ static void SetLevelDefaults (level_info_t *levelinfo) // For maps without a BEHAVIOR, this will be cleared. levelinfo->flags |= LEVEL_LAXMONSTERACTIVATION; } + else + { + levelinfo->flags |= LEVEL_MONSTERFALLINGDAMAGE; + } levelinfo->airsupply = 10; } @@ -487,6 +504,7 @@ static void G_DoParseMapInfo (int lump) SetLevelDefaults (&defaultinfo); SC_OpenLumpNum (lump, "MAPINFO"); + HexenHack=false; while (SC_GetString ()) { @@ -1328,6 +1346,7 @@ void G_InitNew (char *mapname, bool bTitleLevel) } level.time = 0; level.maptime = 0; + level.totaltime = 0; if (!multiplayer || !deathmatch) { @@ -1496,6 +1515,7 @@ void G_DoCompleted (void) wminfo.partime = TICRATE * level.partime; wminfo.sucktime = level.sucktime; wminfo.pnum = consoleplayer; + wminfo.totaltime = level.totaltime; for (i=0 ; i= 230) - arc << level.maptime; + << level.aircontrol + << level.maptime + << level.totaltime; if (arc.IsStoring ()) { arc.WriteName (level.skypic1); arc.WriteName (level.skypic2); } - else if (SaveVersion >= 225) + else { strncpy (level.skypic1, arc.ReadName(), 8); strncpy (level.skypic2, arc.ReadName(), 8); @@ -2360,6 +2384,10 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) arc << t; } } + + // This must be saved, too, of course! + FCanvasTextureInfo::Serialize (arc); + if (!hubLoad) { P_SerializePlayers (arc); diff --git a/src/g_level.h b/src/g_level.h index 99339dbb3..ca8bf1e39 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -98,6 +98,7 @@ #define LEVEL_KEEPFULLINVENTORY UCONST64(0x4000000000) // doesn't reduce the amount of inventory items to 1 +#define LEVEL_MONSTERFALLINGDAMAGE UCONST64(0x10000000000) struct acsdefered_s; class FBehavior; @@ -150,6 +151,8 @@ struct level_info_s char exitpic[9]; char intermusic[9]; + char soundinfo[9]; + char sndseq[9]; FSpecialAction * specialactions; }; typedef struct level_info_s level_info_t; @@ -165,8 +168,9 @@ struct level_locals_s void Tick (); void AddScroller (DScroller *, int secnum); - int time; - int maptime; + int time; // time in the hub + int maptime; // time in the map + int totaltime; // time in the game int starttime; int partime; int sucktime; @@ -252,6 +256,7 @@ struct cluster_info_s int musicorder; int flags; int cdtrack; + char *clustername; unsigned int cdid; }; typedef struct cluster_info_s cluster_info_t; diff --git a/src/g_raven/a_artiegg.cpp b/src/g_raven/a_artiegg.cpp index d00a34522..b74bd03ce 100644 --- a/src/g_raven/a_artiegg.cpp +++ b/src/g_raven/a_artiegg.cpp @@ -80,7 +80,7 @@ bool P_MorphPlayer (player_t *p, const TypeInfo *spawntype) p->momx = p->momy = 0; morphed->ObtainInventory (actor); // Remove all armor - for (item = actor->Inventory; item != NULL; ) + for (item = morphed->Inventory; item != NULL; ) { AInventory *next = item->Inventory; if (item->IsKindOf (RUNTIME_CLASS(AArmor))) @@ -209,6 +209,9 @@ bool P_MorphMonster (AActor *actor, const TypeInfo *spawntype) morphed->tid = actor->tid; morphed->angle = actor->angle; morphed->tracer = actor; + morphed->alpha = actor->alpha; + morphed->RenderStyle = actor->RenderStyle; + morphed->special1 = MORPHTICS + pr_morphmonst(); morphed->special2 = actor->flags & ~MF_JUSTHIT; //morphed->special = actor->special; diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index aac73192a..0c2d812a9 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -34,7 +34,7 @@ IMPLEMENT_ACTOR (AIceChunk, Any, -1, 0) PROP_RadiusFixed (3) PROP_HeightFixed (4) PROP_Flags (MF_DROPOFF) - PROP_Flags2 (MF2_LOGRAV|MF2_CANNOTPUSH|MF2_FLOORCLIP) + PROP_Flags2 (MF2_LOGRAV|MF2_CANNOTPUSH|MF2_FLOORCLIP|MF2_NOTELEPORT) PROP_SpawnState (0) END_DEFAULTS @@ -222,7 +222,7 @@ void A_FreezeDeathChunks (AActor *actor) } if (actor->player) { // attach the player's view to a chunk of ice - AIceChunkHead *head = Spawn (actor->x, actor->y, actor->z+VIEWHEIGHT); + AIceChunkHead *head = Spawn (actor->x, actor->y, actor->z + actor->player->defaultviewheight); head->momz = FixedDiv(head->z-actor->z, actor->height)<<2; head->momx = pr_freeze.Random2 () << (FRACBITS-7); head->momy = pr_freeze.Random2 () << (FRACBITS-7); diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 5ab2e14ed..71db0b0a8 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -71,10 +71,7 @@ void APowerupGiver::Serialize (FArchive &arc) { Super::Serialize (arc); arc << PowerupType; - if (SaveVersion >= 223) - { - arc << EffectTics << BlendColor; - } + arc << EffectTics << BlendColor; } // Powerup ------------------------------------------------------------------- diff --git a/src/g_shared/a_hatetarget.cpp b/src/g_shared/a_hatetarget.cpp index 7c65a88cb..710df7657 100644 --- a/src/g_shared/a_hatetarget.cpp +++ b/src/g_shared/a_hatetarget.cpp @@ -54,7 +54,7 @@ FState AHateTarget::States[] = IMPLEMENT_ACTOR (AHateTarget, Any, 9076, 0) PROP_RadiusFixed (20) PROP_HeightFixed (56) - PROP_Flags (MF_SHOOTABLE|MF_NOSECTOR|MF_NOGRAVITY|MF_NOBLOOD) + PROP_Flags (MF_SHOOTABLE|MF_NOGRAVITY|MF_NOBLOOD) PROP_SpawnState (0) PROP_MassLong (INT_MAX) END_DEFAULTS diff --git a/src/g_shared/a_movingcamera.cpp b/src/g_shared/a_movingcamera.cpp index f0b16bbf1..051117972 100644 --- a/src/g_shared/a_movingcamera.cpp +++ b/src/g_shared/a_movingcamera.cpp @@ -377,6 +377,8 @@ bool APathFollower::Interpolate () dz = z; } + if (CurrNode->Next==NULL) return false; + UnlinkFromWorld (); if (args[2] & 1) { // linear @@ -386,6 +388,8 @@ bool APathFollower::Interpolate () } else { // spline + if (CurrNode->Next->Next==NULL) return false; + x = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->x), FIXED2FLOAT(CurrNode->x), FIXED2FLOAT(CurrNode->Next->x), FIXED2FLOAT(CurrNode->Next->Next->x))); y = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->y), FIXED2FLOAT(CurrNode->y), diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 9f76fb2c4..9320fa165 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -28,10 +28,7 @@ END_DEFAULTS void AAmmo::Serialize (FArchive &arc) { Super::Serialize (arc); - if (SaveVersion >= 223) - { - arc << BackpackAmount << BackpackMaxAmount; - } + arc << BackpackAmount << BackpackMaxAmount; } //=========================================================================== @@ -476,10 +473,7 @@ void AInventory::Serialize (FArchive &arc) { Icon = TexMan.ReadTexture (arc); } - if (SaveVersion >= 226) - { - arc << AR_SOUNDW(PickupSound); - } + arc << AR_SOUNDW(PickupSound); } //=========================================================================== @@ -1281,10 +1275,7 @@ void ABasicArmorPickup::Serialize (FArchive &arc) { Super::Serialize (arc); arc << SavePercent << SaveAmount; - if (SaveVersion >= 222) - { - arc << DropTime; - } + arc << DropTime; } //=========================================================================== @@ -1558,13 +1549,10 @@ void ABasicArmor::AbsorbDamage (int damage, int damageType, int &newdamage) void AHexenArmor::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << Slots[0] << Slots[1] << Slots[2] << Slots[3]; - if (SaveVersion >= 224) - { - arc << Slots[4] - << SlotsIncrement[0] << SlotsIncrement[1] << SlotsIncrement[2] - << SlotsIncrement[3]; - } + arc << Slots[0] << Slots[1] << Slots[2] << Slots[3] + << Slots[4] + << SlotsIncrement[0] << SlotsIncrement[1] << SlotsIncrement[2] + << SlotsIncrement[3]; } //=========================================================================== @@ -1842,10 +1830,7 @@ bool AHealthPickup::Use (bool pickup) void ABackpack::Serialize (FArchive &arc) { Super::Serialize (arc); - if (SaveVersion >= 227) - { - arc << bDepleted; - } + arc << bDepleted; } //=========================================================================== diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index ff709dba7..fd37dc0f0 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -53,7 +53,7 @@ struct FWeaponSlots void Clear (); bool LocateWeapon (const TypeInfo *type, int *const slot, int *const index); ESlotDef AddDefaultWeapon (int slot, const TypeInfo *type); - void RestoreSlots (FConfigFile &config); + int RestoreSlots (FConfigFile &config); void SaveSlots (FConfigFile &config); }; diff --git a/src/g_shared/a_sharedmisc.cpp b/src/g_shared/a_sharedmisc.cpp index 0d98f1ab0..1f367a550 100644 --- a/src/g_shared/a_sharedmisc.cpp +++ b/src/g_shared/a_sharedmisc.cpp @@ -64,6 +64,7 @@ FState ABlood::States[] = IMPLEMENT_ACTOR (ABlood, Any, -1, 130) PROP_Flags (MF_NOBLOCKMAP) + PROP_Flags2 (MF2_NOTELEPORT) PROP_Mass (5) END_DEFAULTS diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 40b5aba70..e093412e7 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -926,11 +926,12 @@ CCMD (addslotdefault) } } -void FWeaponSlots::RestoreSlots (FConfigFile &config) +int FWeaponSlots::RestoreSlots (FConfigFile &config) { char buff[MAX_WEAPONS_PER_SLOT*64]; const char *key, *value; int slot; + int slotsread = 0; buff[sizeof(buff)-1] = 0; @@ -960,7 +961,9 @@ void FWeaponSlots::RestoreSlots (FConfigFile &config) Slots[slot].AddWeapon (tok); tok = strtok (NULL, " "); } + slotsread++; } + return slotsread; } void FWeaponSlots::SaveSlots (FConfigFile &config) diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index a7da8c1ef..78fadd5b2 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -209,14 +209,15 @@ protected: void DrBNumberOuterFont (signed int val, int x, int y, int w=3) const; void DrSmallNumberOuter (int val, int x, int y, bool center) const; - void DrawCrosshair (); void RefreshBackground () const; void GetCurrentAmmo (AAmmo *&ammo1, AAmmo *&ammo2, int &ammocount1, int &ammocount2) const; - AInventory *ValidateInvFirst (int numVisible) const; static void AddBlend (float r, float g, float b, float a, float v_blend[4]); +public: + AInventory *ValidateInvFirst (int numVisible) const; + void DrawCrosshair (); int ST_X, ST_Y; int RelTop; diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 56d38997c..43f6ec8de 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -56,6 +56,7 @@ EXTERN_CVAR (Bool, am_showmonsters) EXTERN_CVAR (Bool, am_showsecrets) EXTERN_CVAR (Bool, am_showitems) EXTERN_CVAR (Bool, am_showtime) +EXTERN_CVAR (Bool, am_showtotaltime) EXTERN_CVAR (Bool, noisedebug) EXTERN_CVAR (Bool, hud_scale) @@ -1146,16 +1147,24 @@ void FBaseStatusBar::Draw (EHudState state) else if (automapactive) { int y, i, time = level.time / TICRATE, height; + int totaltime = level.totaltime / TICRATE; EColorRange highlight = (gameinfo.gametype == GAME_Doom) ? CR_UNTRANSLATED : CR_YELLOW; height = screen->Font->GetHeight () * CleanYfac; // Draw timer + y = 8; if (am_showtime) { sprintf (line, "%02d:%02d:%02d", time/3600, (time%3600)/60, time%60); // Time - screen->DrawText (CR_GREY, SCREENWIDTH - 80*CleanXfac, 8, line, DTA_CleanNoMove, true, TAG_DONE); + screen->DrawText (CR_GREY, SCREENWIDTH - 80*CleanXfac, y, line, DTA_CleanNoMove, true, TAG_DONE); + y+=8*CleanYfac; + } + if (am_showtotaltime) + { + sprintf (line, "%02d:%02d:%02d", totaltime/3600, (totaltime%3600)/60, totaltime%60); // Total time + screen->DrawText (CR_GREY, SCREENWIDTH - 80*CleanXfac, y, line, DTA_CleanNoMove, true, TAG_DONE); } // Draw map name diff --git a/src/g_strife/a_acolyte.cpp b/src/g_strife/a_acolyte.cpp index 82533342d..0d0420f10 100644 --- a/src/g_strife/a_acolyte.cpp +++ b/src/g_strife/a_acolyte.cpp @@ -316,6 +316,7 @@ IMPLEMENT_ACTOR (AAcolyteToBe, Strife, 201, 0) PROP_RadiusFixed (20) PROP_HeightFixed (56) PROP_StrifeType (29) + PROP_Tag ("PEASANT") PROP_DeathSound ("becoming/death") END_DEFAULTS diff --git a/src/g_strife/a_macil.cpp b/src/g_strife/a_macil.cpp index 3a99f297c..c8c16f7d2 100644 --- a/src/g_strife/a_macil.cpp +++ b/src/g_strife/a_macil.cpp @@ -123,6 +123,11 @@ void AMacil1::NoBlockingSet () int AMacil1::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, int damagetype) { + target = source; + if (PainState != NULL) + { + SetState (PainState); + } return -1; } @@ -178,5 +183,5 @@ int AMacil2::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, i { if (inflictor->IsKindOf (RUNTIME_CLASS(ASpectralLightningV1))) return -1; - return damage; + return Super::TakeSpecialDamage(inflictor, source, damage, damagetype); } diff --git a/src/g_strife/a_oracle.cpp b/src/g_strife/a_oracle.cpp index 812072087..806d24cb7 100644 --- a/src/g_strife/a_oracle.cpp +++ b/src/g_strife/a_oracle.cpp @@ -83,5 +83,5 @@ int AOracle::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, i { if (inflictor->IsKindOf (RUNTIME_CLASS(ASpectralLightningV1))) return -1; - return damage; + return Super::TakeSpecialDamage(inflictor, source, damage, damagetype); } diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 190f8f014..1efa5d64b 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -1512,9 +1512,10 @@ IMPLEMENT_ACTOR (AHEGrenade, Strife, -1, 0) PROP_Flags (MF_NOBLOCKMAP|MF_DROPOFF|MF_MISSILE) PROP_Flags2 (MF2_FLOORCLIP|MF2_NOTELEPORT|MF2_PCROSS|MF2_IMPACT|MF2_DOOMBOUNCE) PROP_Flags3 (MF3_CANBOUNCEWATER) - PROP_Flags4 (MF4_STRIFEDAMAGE) + PROP_Flags4 (MF4_STRIFEDAMAGE|MF4_NOBOUNCESOUND) PROP_MaxStepHeight (4) PROP_StrifeType (106) + PROP_BounceFactor((FRACUNIT*5/10)) PROP_SeeSound ("weapons/hegrenadeshoot") PROP_DeathSound ("weapons/hegrenadebang") END_DEFAULTS @@ -1560,9 +1561,10 @@ IMPLEMENT_ACTOR (APhosphorousGrenade, Strife, -1, 0) PROP_Flags (MF_NOBLOCKMAP|MF_DROPOFF|MF_MISSILE) PROP_Flags2 (MF2_FLOORCLIP|MF2_NOTELEPORT|MF2_PCROSS|MF2_IMPACT|MF2_DOOMBOUNCE) PROP_Flags3 (MF3_CANBOUNCEWATER) - PROP_Flags4 (MF4_STRIFEDAMAGE) + PROP_Flags4 (MF4_STRIFEDAMAGE|MF4_NOBOUNCESOUND) PROP_MaxStepHeight (4) PROP_StrifeType (107) + PROP_BounceFactor((FRACUNIT*5/10)) PROP_SeeSound ("weapons/phgrenadeshoot") PROP_DeathSound ("weapons/phgrenadebang") END_DEFAULTS @@ -1666,9 +1668,19 @@ void A_Burnination (AActor *self) yofs = clamp (yofs, 12, 31); } + fixed_t x = self->x + (xofs << FRACBITS); + fixed_t y = self->y + (yofs << FRACBITS); + sector_t * sector = R_PointInSubsector(x, y)->sector; + + // The sector's floor is too high so spawn the flame elsewhere. + if (sector->floorplane.ZatPoint(x, y) > self->z + self->MaxStepHeight) + { + x = self->x; + y = self->y; + } + AActor *drop = Spawn ( - self->x + (xofs << FRACBITS), - self->y + (yofs << FRACBITS), + x, y, self->z + 4*FRACUNIT); if (drop != NULL) { diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index f1eaa390d..e42242c48 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -395,11 +395,7 @@ void FGameConfigFile::DoGameSetup (const char *gamename) } strcpy (subsection, "WeaponSlots"); - if (SetSection (section)) - { - LocalWeapons.RestoreSlots (*this); - } - else + if (!SetSection (section) || !LocalWeapons.RestoreSlots (*this)) { SetupWeaponList (gamename); } diff --git a/src/info.h b/src/info.h index 6ac5e959e..64dc6a75d 100644 --- a/src/info.h +++ b/src/info.h @@ -271,6 +271,7 @@ enum ADEF_MeleeRange, ADEF_MaxDropOffHeight, ADEF_MaxStepHeight, + ADEF_BounceFactor, ADEF_SpawnState, ADEF_SeeState, @@ -313,9 +314,6 @@ enum ADEF_Powerup_Color, ADEF_PowerupGiver_EffectTics, - ADEF_Key_KeyNumber, - ADEF_Key_AltKeyNumber, - ADEF_Ammo_BackpackAmount, ADEF_Ammo_BackpackMaxAmount, diff --git a/src/infodefaults.cpp b/src/infodefaults.cpp index afac6c7f0..130121d8d 100644 --- a/src/infodefaults.cpp +++ b/src/infodefaults.cpp @@ -210,6 +210,7 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint) case ADEF_MeleeRange: actor->meleerange = dataint; break; case ADEF_MaxDropOffHeight: actor->MaxDropOffHeight = dataint; break; case ADEF_MaxStepHeight: actor->MaxStepHeight = dataint; break; + case ADEF_BounceFactor: actor->bouncefactor = dataint; break; case ADEF_SpawnState: actor->SpawnState = datastate; break; case ADEF_SeeState: actor->SeeState = datastate; break; @@ -265,9 +266,6 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint) case ADEF_Powerup_EffectTics: power->EffectTics = dataint; break; case ADEF_Powerup_Color: power->BlendColor = dataint; break; - case ADEF_Key_KeyNumber: key->KeyNumber = dataint; break; - case ADEF_Key_AltKeyNumber: key->AltKeyNumber = dataint; break; - case ADEF_Ammo_BackpackAmount: ammo->BackpackAmount = dataint; break; case ADEF_Ammo_BackpackMaxAmount:ammo->BackpackMaxAmount = dataint; break; diff --git a/src/infomacros.h b/src/infomacros.h index c8a1b6901..c2589658c 100644 --- a/src/infomacros.h +++ b/src/infomacros.h @@ -253,6 +253,7 @@ public: #define PROP_MeleeRange(x) ADD_FIXD_PROP(ADEF_MeleeRange,x) #define PROP_MaxDropOffHeight(x) ADD_FIXD_PROP(ADEF_MaxDropOffHeight,x) #define PROP_MaxStepHeight(x) ADD_FIXD_PROP(ADEF_MaxStepHeight,x) +#define PROP_BounceFactor(x) ADD_LONG_PROP(ADEF_BounceFactor,x) #define PROP_SpawnState(x) ADD_BYTE_PROP(ADEF_SpawnState,x) #define PROP_SeeState(x) ADD_BYTE_PROP(ADEF_SeeState,x) @@ -297,9 +298,6 @@ public: #define PROP_Powerup_EffectTics(x) ADD_LONG_PROP(ADEF_Powerup_EffectTics,x) #define PROP_Powerup_Color(a,r,g,b) ADD_LONG_PROP(ADEF_Powerup_Color,((a)<<24)|((r)<<16)|((g)<<8)|(b)) -#define PROP_Key_KeyNumber(x) ADD_BYTE_PROP(ADEF_Key_KeyNumber,x) -#define PROP_Key_AltKeyNumber(x) ADD_BYTE_PROP(ADEF_Key_AltKeyNumber,x) - #define PROP_Ammo_BackpackAmount(x) ADD_WORD_PROP(ADEF_Ammo_BackpackAmount,x) #define PROP_Ammo_BackpackMaxAmount(x) ADD_WORD_PROP(ADEF_Ammo_BackpackMaxAmount,x) diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 06a5b4f87..e6753d511 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -311,7 +311,10 @@ void cht_DoCheat (player_t *player, int cheat) break; case CHT_ALLARTI: - cht_Give (player, "artifacts"); + for (int i=0;i<25;i++) + { + cht_Give (player, "artifacts"); + } msg = GStrings("TXT_CHEATARTIFACTS3"); break; diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 2d8d75011..8a48aab7a 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -645,6 +645,7 @@ void M_ReadSaveStrings () if (NULL != (png = M_VerifyPNG (file))) { char *ver = M_GetPNGText (png, "ZDoom Save Version"); + char *engine = M_GetPNGText (png, "Engine"); if (ver != NULL) { if (!M_GetPNGText (png, "Title", title, SAVESTRINGSIZE)) @@ -652,7 +653,8 @@ void M_ReadSaveStrings () strncpy (title, I_FindName(&c_file), SAVESTRINGSIZE); } if (strncmp (ver, SAVESIG, 9) == 0 && - atoi (ver+9) >= MINSAVEVER) + atoi (ver+9) >= MINSAVEVER && + engine != NULL) { // Was saved with a compatible ZDoom version, // so check if it's for the current game. @@ -2278,7 +2280,7 @@ static void M_ChangeAutoAim (int choice) static void M_EditPlayerName (int choice) { // we are going to be intercepting all chars - genStringEnter = 1; + genStringEnter = 2; genStringEnd = M_PlayerNameChanged; genStringLen = MAXPLAYERNAME; @@ -2477,7 +2479,7 @@ BOOL M_Responder (event_t *ev) { ch = ev->data1; if (saveCharIndex < genStringLen && - (size_t)SmallFont->StringWidth (savegamestring) < (genStringLen-1)*8) + (genStringEnter==2 || (size_t)SmallFont->StringWidth (savegamestring) < (genStringLen-1)*8)) { savegamestring[saveCharIndex] = ch; savegamestring[++saveCharIndex] = 0; diff --git a/src/m_misc.cpp b/src/m_misc.cpp index a21985c63..bdb13e085 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -311,7 +311,7 @@ string GetUserFile (string file, bool nodir) if (!nodir) { struct stat info; - if (stat (path, &info) == -1) + if (stat (path.GetChars(), &info) == -1) { if (mkdir (path.GetChars(), S_IRUSR | S_IWUSR | S_IXUSR) == -1) { @@ -346,6 +346,7 @@ void STACK_ARGS M_SaveDefaults () } GameConfig->WriteConfigFile (); delete GameConfig; + GameConfig = NULL; } diff --git a/src/m_options.cpp b/src/m_options.cpp index 2ebb99e88..9df06dd6c 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -79,6 +79,7 @@ // Data. #include "m_menu.h" +EXTERN_CVAR(Bool, nomonsterinterpolation) // // defaulted values // @@ -537,12 +538,21 @@ EXTERN_CVAR (Bool, am_showitems) EXTERN_CVAR (Bool, am_showmonsters) EXTERN_CVAR (Bool, am_showsecrets) EXTERN_CVAR (Bool, am_showtime) +EXTERN_CVAR (Int, am_map_secrets) +EXTERN_CVAR (Bool, am_showtotaltime) +EXTERN_CVAR (Bool, am_drawmapback) static value_t MapColorTypes[] = { { 1, "Custom" }, { 0, "Traditional Doom" } }; +static value_t SecretTypes[] = { + { 0, "Never" }, + { 1, "Only when found" }, + { 2, "Always" }, +}; + static menuitem_t AutomapItems[] = { { discrete, "Map color set", {&am_usecustomcolors}, {2.0}, {0.0}, {0.0}, {MapColorTypes} }, { more, "Set custom colors", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t*)StartMapColorsMenu} }, @@ -554,6 +564,9 @@ static menuitem_t AutomapItems[] = { { discrete, "Show monster counts", {&am_showmonsters}, {2.0}, {0.0}, {0.0}, {OnOff} }, { discrete, "Show secret counts", {&am_showsecrets}, {2.0}, {0.0}, {0.0}, {OnOff} }, { discrete, "Show time elapsed", {&am_showtime}, {2.0}, {0.0}, {0.0}, {OnOff} }, + { discrete, "Show total time elapsed", {&am_showtotaltime}, {2.0}, {0.0}, {0.0}, {OnOff} }, + { discrete, "Show secrets on map", {&am_map_secrets}, {3.0}, {0.0}, {0.0}, {SecretTypes} }, + { discrete, "Draw automap background", {&am_drawmapback}, {2.0}, {0.0}, {0.0}, {OnOff} }, }; menu_t AutomapMenu = @@ -592,6 +605,13 @@ EXTERN_CVAR (Color, am_ovunseencolor) EXTERN_CVAR (Color, am_ovtelecolor) EXTERN_CVAR (Color, am_intralevelcolor) EXTERN_CVAR (Color, am_interlevelcolor) +EXTERN_CVAR (Color, am_secretsectorcolor) +EXTERN_CVAR (Color, am_thingcolor_friend) +EXTERN_CVAR (Color, am_thingcolor_monster) +EXTERN_CVAR (Color, am_thingcolor_item) +EXTERN_CVAR (Color, am_ovthingcolor_friend) +EXTERN_CVAR (Color, am_ovthingcolor_monster) +EXTERN_CVAR (Color, am_ovthingcolor_item) static menuitem_t MapColorsItems[] = { { rsafemore, "Restore default custom colors", {NULL}, {0}, {0}, {0}, {(value_t*)DefaultCustomColors} }, @@ -607,10 +627,14 @@ static menuitem_t MapColorsItems[] = { { colorpicker, "Locked doors", {&am_lockedcolor}, {0}, {0}, {0}, {0} }, { colorpicker, "Teleporter to the same map", {&am_intralevelcolor}, {0}, {0}, {0}, {0} }, { colorpicker, "Teleporter to a different map", {&am_interlevelcolor}, {0}, {0}, {0}, {0} }, + { colorpicker, "Secret sector", {&am_secretsectorcolor}, {0}, {0}, {0}, {0} }, { redtext, " ", {NULL}, {0}, {0}, {0}, {0} }, { colorpicker, "Invisible 2-sided walls (for cheat)", {&am_tswallcolor}, {0}, {0}, {0}, {0} }, { colorpicker, "Secret walls (for cheat)", {&am_secretwallcolor}, {0}, {0}, {0}, {0} }, { colorpicker, "Actors (for cheat)", {&am_thingcolor}, {0}, {0}, {0}, {0} }, + { colorpicker, "Monsters (for cheat)", {&am_thingcolor_monster}, {0}, {0}, {0}, {0} }, + { colorpicker, "Friends (for cheat)", {&am_thingcolor_friend}, {0}, {0}, {0}, {0} }, + { colorpicker, "Items (for cheat)", {&am_thingcolor_item}, {0}, {0}, {0}, {0} }, { redtext, " ", {NULL}, {0}, {0}, {0}, {0} }, { colorpicker, "You (overlay)", {&am_ovyourcolor}, {0}, {0}, {0}, {0} }, { colorpicker, "1-sided walls (overlay)", {&am_ovwallcolor}, {0}, {0}, {0}, {0} }, @@ -618,6 +642,9 @@ static menuitem_t MapColorsItems[] = { { colorpicker, "Not-yet-seen walls (overlay)", {&am_ovunseencolor}, {0}, {0}, {0}, {0} }, { colorpicker, "Teleporter (overlay)", {&am_ovtelecolor}, {0}, {0}, {0}, {0} }, { colorpicker, "Actors (overlay) (for cheat)", {&am_ovthingcolor}, {0}, {0}, {0}, {0} }, + { colorpicker, "Monsters (overlay) (for cheat)", {&am_ovthingcolor_monster}, {0}, {0}, {0}, {0} }, + { colorpicker, "Friends (overlay) (for cheat)", {&am_ovthingcolor_friend}, {0}, {0}, {0}, {0} }, + { colorpicker, "Items (overlay) (for cheat)", {&am_ovthingcolor_item}, {0}, {0}, {0}, {0} }, }; menu_t MapColorsMenu = @@ -625,7 +652,7 @@ menu_t MapColorsMenu = "CUSTOMIZE MAP COLORS", 0, sizeof(MapColorsItems)/sizeof(MapColorsItems[0]), - 42, + 48, MapColorsItems, }; @@ -896,7 +923,8 @@ static menuitem_t DMFlagsItems[] = { { bitflag, "Allow jump", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_JUMP} }, { bitflag, "Allow freelook", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FREELOOK} }, { bitflag, "Allow FOV", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FOV} }, - { bitflag, "Allow BFG aiming", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NO_FREEAIMBFG} } + { bitflag, "Allow BFG aiming", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NO_FREEAIMBFG} }, + { bitflag, "Multi. weapons in coop", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_COOP_WEAPON_SPAWN} }, }; static menu_t DMFlagsMenu = @@ -925,7 +953,8 @@ static menuitem_t CompatibilityItems[] = { { bitflag, "Spawn item drops on the floor", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_NOTOSSDROPS} }, { bitflag, "All special lines can block ", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_USEBLOCKING} }, { bitflag, "Disable BOOM door light effect", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_NODOORLIGHT} }, - { bitflag, "Raven scroll types use original speed", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_RAVENSCROLL} }, + { bitflag, "Raven scrollers use original speed", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_RAVENSCROLL} }, + { discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} }, }; static menu_t CompatibilityMenu = diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 15eeb058d..09a0aa436 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -957,18 +957,29 @@ static void PickConversationReply () takestuff = true; if (reply->GiveType != NULL) { - AInventory *item = static_cast (Spawn (reply->GiveType, 0, 0, 0)); - // Items given here should not count as items! - if (item->flags & MF_COUNTITEM) + if (reply->GiveType->IsDescendantOf(RUNTIME_CLASS(AWeapon))) { - level.total_items--; - item->flags &= ~MF_COUNTITEM; + if (players[consoleplayer].mo->FindInventory(reply->GiveType) != NULL) + { + takestuff = false; + } } - item->flags |= MF_DROPPED; - if (!item->TryPickup (players[consoleplayer].mo)) + + if (takestuff) { - item->Destroy (); - takestuff = false; + AInventory *item = static_cast (Spawn (reply->GiveType, 0, 0, 0)); + // Items given here should not count as items! + if (item->flags & MF_COUNTITEM) + { + level.total_items--; + item->flags &= ~MF_COUNTITEM; + } + item->flags |= MF_DROPPED; + if (!item->TryPickup (players[consoleplayer].mo)) + { + item->Destroy (); + takestuff = false; + } } } diff --git a/src/p_doors.cpp b/src/p_doors.cpp index 4e7ba0783..51c9fec71 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -631,12 +631,6 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec) void DAnimatedDoor::Serialize (FArchive &arc) { - // If you have a pre-224 savegame with an active animated door, then you're out - // of luck. - if (SaveVersion < 224) - { - I_Error ("Can't load pre-2.0.93 savegames with active animated doors.\n"); - } Super::Serialize (arc); arc << m_Line1 << m_Line2 << m_Frame diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index af65d2016..ef960678e 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -543,8 +543,9 @@ void P_NewChaseDir (AActor *actor) deltay = actor->target->y - actor->y; // [RH] Make monsters run away from frightening players - if (actor->target->player != NULL && - (actor->target->player->cheats & CF_FRIGHTENING)) + if ((actor->target->player != NULL && + (actor->target->player->cheats & CF_FRIGHTENING)) || + actor->flags4 & MF4_FRIGHTENED) { deltax = -deltax; deltay = -deltay; @@ -1709,6 +1710,11 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi } actor->target = NULL; actor->flags |= MF_JUSTATTACKED; + if (actor->goal != NULL && actor->goal->args[1] != 0) + { + actor->flags4 |= MF4_INCOMBAT; + actor->SetState (actor->SpawnState); + } actor->flags &= ~MF_INCHASE; return; } @@ -1749,8 +1755,9 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi } // [RH] Scared monsters attack less frequently - if (actor->target->player == NULL || - !(actor->target->player->cheats & CF_FRIGHTENING) || + if (((actor->target->player == NULL || + !(actor->target->player->cheats & CF_FRIGHTENING)) && + !(actor->flags4 & MF4_FRIGHTENED)) || pr_scaredycat() < 43) { // check for melee attack @@ -1969,6 +1976,7 @@ void A_XXScream (AActor *actor) // PROC P_DropItem // //--------------------------------------------------------------------------- +CVAR(Int, sv_dropstyle, 0, CVAR_SERVERINFO | CVAR_ARCHIVE); AInventory *P_DropItem (AActor *source, const TypeInfo *type, int special, int chance) { @@ -1980,7 +1988,10 @@ AInventory *P_DropItem (AActor *source, const TypeInfo *type, int special, int c spawnz = source->z; if (!(compatflags & COMPATF_NOTOSSDROPS)) { - if (gameinfo.gametype == GAME_Strife) + int style = sv_dropstyle; + if (style==0) style= (gameinfo.gametype == GAME_Strife)? 2:1; + + if (style==2) { spawnz += 24*FRACUNIT; } @@ -2031,7 +2042,10 @@ AInventory *P_DropItem (AActor *source, const TypeInfo *type, int special, int c void P_TossItem (AActor *item) { - if (gameinfo.gametype == GAME_Strife) + int style = sv_dropstyle; + if (style==0) style= (gameinfo.gametype == GAME_Strife)? 2:1; + + if (style==2) { item->momx += pr_dropitem.Random2(7) << FRACBITS; item->momy += pr_dropitem.Random2(7) << FRACBITS; diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 8a90acd6a..846d68927 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -654,6 +654,15 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag) } +static int P_FindSectorFromTagLinear (int tag, int start) +{ + for (int i=start+1;i= 0) + while ((secnum = FindSector (tag, secnum)) >= 0) { sec = §ors[secnum]; diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index ecf8ef4ce..16cb3e314 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -372,8 +372,10 @@ void AActor::Die (AActor *source, AActor *inflictor) flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SKULLFLY); if (!(flags4 & MF4_DONTFALL)) flags&=~MF_NOGRAVITY; flags |= MF_DROPOFF; - if (flags3 & MF3_ISMONSTER) - { // [RH] Only monsters get to be corpses. + if ((flags3 & MF3_ISMONSTER) || RaiseState != NULL) + { // [RH] Only monsters get to be corpses. + // Objects with a raise state should get the flag as well so they can + // be revived by an Arch-Vile. Batman Doom needs this. flags |= MF_CORPSE; } // [RH] Allow the death height to be overridden using metadata. diff --git a/src/p_lnspec.h b/src/p_lnspec.h index 93b5531cc..cbc922233 100644 --- a/src/p_lnspec.h +++ b/src/p_lnspec.h @@ -56,6 +56,7 @@ typedef enum { Door_Animated = 14, Autosave = 15, // [RH] Save the game *now* + Transfer_WallLight = 16, Floor_LowerByValue = 20, Floor_LowerToLowest = 21, diff --git a/src/p_local.h b/src/p_local.h index a0ba67e55..84b08d5d5 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -35,7 +35,6 @@ #define MAXHEALTH (deh.MaxHealth) //100 #define MAXMORPHHEALTH 30 -#define VIEWHEIGHT (41*FRACUNIT) #define BONUSADD 6 diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index d7d7cb5aa..9a090e87b 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -241,10 +241,7 @@ void AActor::Serialize (FArchive &arc) { picnum = TexMan.ReadTexture (arc); } - if (SaveVersion >= 227) - { - floorpic = TexMan.ReadTexture (arc); - } + floorpic = TexMan.ReadTexture (arc); } arc << TIDtoHate; if (TIDtoHate == 0) @@ -264,12 +261,8 @@ void AActor::Serialize (FArchive &arc) << floorz << ceilingz << dropoffz - << floorsector; - if (SaveVersion < 227) - { - arc << floorpic; - } - arc << radius + << floorsector + << radius << height << momx << momy @@ -330,24 +323,18 @@ void AActor::Serialize (FArchive &arc) << IDeathState << EDeathState << RaiseState - << WoundState; - if (SaveVersion >= 230) - { - arc << MaxDropOffHeight << MaxStepHeight; - } - if (SaveVersion >= 229) - { - arc << HealState - << YesState - << NoState - << GreetingsState - << meleerange - << CrushState; - } - if (SaveVersion >= 224) - { - arc << DamageType; - } + << WoundState + << HealState + << YesState + << NoState + << GreetingsState + << CrushState + << MaxDropOffHeight + << MaxStepHeight + << bouncefactor + << meleerange + << DamageType; + if (arc.IsStoring ()) { int convnum = 0; @@ -355,8 +342,6 @@ void AActor::Serialize (FArchive &arc) if (Conversation != NULL) { - if (strcmp (Conversation->SpeakerName, "RICHTER") == 0) - Conversation = Conversation; for (i = 0; i < StrifeDialogues.Size(); ++i) { if (StrifeDialogues[i] == GetDefault()->Conversation) @@ -1080,12 +1065,13 @@ bool AActor::FloorBounceMissile (secplane_t &plane) } // The reflected velocity keeps only about 70% of its original speed - momx = MulScale30 (momx - MulScale15 (plane.a, dot), 751619277); - momy = MulScale30 (momy - MulScale15 (plane.b, dot), 751619277); - momz = MulScale30 (momz - MulScale15 (plane.c, dot), 751619277); + long bouncescale = 0x4000 * bouncefactor; + momx = MulScale30 (momx - MulScale15 (plane.a, dot), bouncescale); + momy = MulScale30 (momy - MulScale15 (plane.b, dot), bouncescale); + momz = MulScale30 (momz - MulScale15 (plane.c, dot), bouncescale); angle = R_PointToAngle2 (0, 0, momx, momy); - if (SeeSound) + if (SeeSound && !(flags4 & MF4_NOBOUNCESOUND)) { S_SoundID (this, CHAN_VOICE, SeeSound, 1, ATTN_IDLE); } @@ -1703,7 +1689,7 @@ void P_MonsterFallingDamage (AActor *mo) int damage; int mom; - if (gameinfo.gametype != GAME_Hexen) + if (!(level.flags&LEVEL_MONSTERFALLINGDAMAGE)) return; mom = abs(mo->momz); @@ -1734,7 +1720,7 @@ void P_ZMovement (AActor *mo) if (mo->player && mo->player->mo == mo && mo->z < mo->floorz) { mo->player->viewheight -= mo->floorz - mo->z; - mo->player->deltaviewheight = (VIEWHEIGHT - mo->player->viewheight)>>3; + mo->player->deltaviewheight = mo->player->GetDeltaViewHeight(); } if (!(mo->flags2&MF2_FLOATBOB)) mo->z += mo->momz; @@ -2730,7 +2716,7 @@ void AActor::Tick () if (player && player->mo == this) { player->viewheight -= onmo->z + onmo->height - z; - fixed_t deltaview = (VIEWHEIGHT - player->viewheight)>>3; + fixed_t deltaview = player->GetDeltaViewHeight(); if (deltaview > player->deltaviewheight) { player->deltaviewheight = deltaview; @@ -2935,6 +2921,7 @@ BEGIN_DEFAULTS (AActor, Any, -1, 0) PROP_MeleeRange(44) // MELEERANGE(64) - 20 PROP_MaxDropOffHeight(24) PROP_MaxStepHeight(24) + PROP_BounceFactor(FRACUNIT*7/10) END_DEFAULTS //========================================================================== @@ -3222,7 +3209,7 @@ void AActor::AdjustFloorClip () if (player && player->mo == this && oldclip != floorclip) { player->viewheight -= oldclip - floorclip; - player->deltaviewheight = (VIEWHEIGHT - player->viewheight) >> 3; + player->deltaviewheight = player->GetDeltaViewHeight(); } } @@ -3349,7 +3336,7 @@ void P_SpawnPlayer (mapthing2_t *mthing) p->morphTics = 0; p->extralight = 0; p->fixedcolormap = 0; - p->viewheight = VIEWHEIGHT; + p->viewheight = p->defaultviewheight = gameinfo.gametype == GAME_Hexen? 48*FRACUNIT : 41*FRACUNIT; p->inconsistant = 0; p->attacker = NULL; p->spreecount = 0; @@ -3666,8 +3653,8 @@ void P_SpawnMapThing (mapthing2_t *mthing, int position) if (deathmatch && info->flags & MF_NOTDMATCH) return; - // [RH] don't spawn extra weapons in coop - if (multiplayer && !deathmatch) + // [RH] don't spawn extra weapons in coop if so desired + if (multiplayer && !deathmatch && (dmflags&DF_NO_COOP_WEAPON_SPAWN)) { if (i->IsDescendantOf (RUNTIME_CLASS(AWeapon))) { diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 6b688ce3e..569d78478 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -126,7 +126,8 @@ void P_SerializeWorld (FArchive &arc) << sec->sky << sec->MoreFlags << sec->FloorSkyBox << sec->CeilingSkyBox - << sec->ZoneNumber; + << sec->ZoneNumber + << sec->oldspecial; if (arc.IsStoring ()) { arc << sec->ColorMap->Color diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 81c2d83ef..cbdbb04d1 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -822,6 +822,7 @@ void P_LoadSectors (int lump) ss->special = LittleShort(ms->special); else // [RH] Translate to new sector special ss->special = P_TranslateSectorSpecial (LittleShort(ms->special)); + ss->oldspecial = !!(ss->special&SECRET_MASK); ss->tag = LittleShort(ms->tag); ss->thinglist = NULL; ss->touching_thinglist = NULL; // phares 3/14/98 diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 2cfe4ffe9..036b34000 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -93,14 +93,6 @@ void DScroller::Serialize (FArchive &arc) << m_LastHeight << m_vdx << m_vdy << m_Accel; - if (SaveVersion < 228) - { - if (m_Type == sc_carry) - { - m_dx = FixedDiv (m_dx, CARRYFACTOR); - m_dy = FixedDiv (m_dy, CARRYFACTOR); - } - } } DPusher::DPusher () @@ -218,14 +210,21 @@ static void P_InitAnimDefs () int picnum = TexMan.CheckForTexture (sc_String, isflat ? FTexture::TEX_Flat : FTexture::TEX_Wall, texflags); if (picnum != -1) { - FTexture *warper; - if (type2) // [GRB] - warper = new FWarp2Texture (TexMan[picnum]); - else - warper = new FWarpTexture (TexMan[picnum]); - TexMan.ReplaceTexture (picnum, warper, false); + FTexture * warper = TexMan[picnum]; - // No decals on warping textures, by default + // don't warp a texture more than once + if (!warper->bWarped) + { + if (type2) // [GRB] + warper = new FWarp2Texture (warper); + else + warper = new FWarpTexture (warper); + TexMan.ReplaceTexture (picnum, warper, false); + } + + // No decals on warping textures, by default. + // Warping information is taken from the last warp + // definition for this texture. warper->bNoDecals = true; if (SC_GetString ()) { @@ -818,7 +817,7 @@ BOOL P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType) if (activationType == SPAC_OTHERCROSS) { if (lineActivation == SPAC_CROSS && line->special >= Generic_Floor && - line->special <= Generic_Crusher) + line->special <= Generic_Crusher && !(mo->flags2&MF2_NOTELEPORT)) { return (line->flags & ML_MONSTERSCANACTIVATE) != 0; } @@ -829,7 +828,7 @@ BOOL P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType) { return false; } - if (!mo->player && + if (mo && !mo->player && !(mo->flags & MF_MISSILE) && !(line->flags & ML_MONSTERSCANACTIVATE) && (activationType != SPAC_MCROSS || lineActivation != SPAC_MCROSS)) @@ -1302,6 +1301,95 @@ void DLightTransfer::DoTransfer (BYTE level, int target, bool floor) } } + +class DWallLightTransfer : public DThinker +{ + enum + { + WLF_SIDE1=1, + WLF_SIDE2=2, + WLF_NOFAKECONTRAST=4 + }; + + DECLARE_ACTOR (DWallLightTransfer, DThinker) +public: + DWallLightTransfer (sector_t *srcSec, int target, BYTE flags); + void Serialize (FArchive &arc); + void Tick (); + +protected: + static void DoTransfer (BYTE level, int target, BYTE flags); + + BYTE LastLight; + BYTE Flags; + sector_t *Source; + int TargetID; +}; + +IMPLEMENT_CLASS (DWallLightTransfer) + +void DWallLightTransfer::Serialize (FArchive &arc) +{ + Super::Serialize (arc); + arc << LastLight << Source << TargetID << Flags; +} + +DWallLightTransfer::DWallLightTransfer (sector_t *srcSec, int target, BYTE flags) +{ + int linenum; + int wallflags; + + Source = srcSec; + TargetID = target; + Flags = flags; + DoTransfer (LastLight = srcSec->lightlevel, target, Flags); + + if (!(flags&WLF_NOFAKECONTRAST)) wallflags = WALLF_AUTOCONTRAST|WALLF_ABSLIGHTING; + else wallflags = WALLF_ABSLIGHTING; + + for (linenum = -1; (linenum = P_FindLineFromID (target, linenum)) >= 0; ) + { + if (flags & WLF_SIDE1 && lines[linenum].sidenum[0]!=NO_SIDE) + sides[lines[linenum].sidenum[0]].Flags |= wallflags; + + if (flags & WLF_SIDE2 && lines[linenum].sidenum[1]!=NO_SIDE) + sides[lines[linenum].sidenum[1]].Flags |= wallflags; + } + ChangeStatNum(STAT_LIGHTTRANSFER); +} + +void DWallLightTransfer::Tick () +{ + BYTE light = Source->lightlevel; + + if (light != LastLight) + { + LastLight = light; + DoTransfer (light, TargetID, Flags); + } +} + +void DWallLightTransfer::DoTransfer (BYTE lightlevel, int target, BYTE flags) +{ + int linenum; + + for (linenum = -1; (linenum = P_FindLineFromID (target, linenum)) >= 0; ) + { + line_t * line = &lines[linenum]; + + if (flags & WLF_SIDE1 && line->sidenum[0]!=NO_SIDE) + { + sides[line->sidenum[0]].Light = (BYTE)lightlevel; + } + + if (flags & WLF_SIDE2 && line->sidenum[1]!=NO_SIDE) + { + sides[line->sidenum[1]].Light = (BYTE)lightlevel; + } + } +} + + // // P_SpawnSpecials // @@ -1503,6 +1591,12 @@ void P_SpawnSpecials (void) new DLightTransfer (sides[*lines[i].sidenum].sector, lines[i].args[0], false); break; + // [Graf Zahl] Add support for setting lighting + // per wall independently + case Transfer_WallLight: + new DWallLightTransfer (sides[*lines[i].sidenum].sector, lines[i].args[0], lines[i].args[1]); + break; + // [RH] ZDoom Static_Init settings case Static_Init: switch (lines[i].args[1]) diff --git a/src/p_tick.cpp b/src/p_tick.cpp index a09bd464b..f894ea778 100644 --- a/src/p_tick.cpp +++ b/src/p_tick.cpp @@ -89,4 +89,5 @@ void P_Ticker (void) // for par times level.time++; level.maptime++; + level.totaltime++; } diff --git a/src/p_user.cpp b/src/p_user.cpp index 4aadf710a..93507dc75 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -108,8 +108,12 @@ void player_s::SetLogNumber (int num) } else { - FMemLump data = Wads.ReadLump (lumpnum); - SetLogText ((char *)data.GetMem()); + int length=Wads.LumpLength(lumpnum); + char *data= new char[length+1]; + Wads.ReadLump (lumpnum, data); + data[length]=0; + SetLogText (data); + delete[] data; // Print log text to console AddToConsole(-1, TEXTCOLOR_GOLD); @@ -130,10 +134,7 @@ void APlayerPawn::Serialize (FArchive &arc) { Super::Serialize (arc); - if (SaveVersion >= 229) - { - arc << JumpZ; - } + arc << JumpZ; } void APlayerPawn::BeginPlay () @@ -144,6 +145,9 @@ void APlayerPawn::BeginPlay () void APlayerPawn::AddInventory (AInventory *item) { + // Don't add to the inventory of dead players. + if (health<=0) return; + // Adding inventory to a voodoo doll should add it to the real player instead. if (player != NULL && player->mo != this) { @@ -551,9 +555,11 @@ void P_CalcHeight (player_t *player) } } + fixed_t defaultviewheight = player->defaultviewheight; + if (player->cheats & CF_NOMOMENTUM) { - player->viewz = player->mo->z + VIEWHEIGHT; + player->viewz = player->mo->z + defaultviewheight; if (player->viewz > player->mo->ceilingz-4*FRACUNIT) player->viewz = player->mo->ceilingz-4*FRACUNIT; @@ -585,14 +591,14 @@ void P_CalcHeight (player_t *player) { player->viewheight += player->deltaviewheight; - if (player->viewheight > VIEWHEIGHT) + if (player->viewheight > defaultviewheight) { - player->viewheight = VIEWHEIGHT; + player->viewheight = defaultviewheight; player->deltaviewheight = 0; } - else if (player->viewheight < VIEWHEIGHT/2) + else if (player->viewheight < (defaultviewheight>>1)) { - player->viewheight = VIEWHEIGHT/2; + player->viewheight = defaultviewheight>>1; if (player->deltaviewheight <= 0) player->deltaviewheight = 1; } @@ -1370,6 +1376,7 @@ void player_s::Serialize (FArchive &arc) << DesiredFOV << FOV << viewz << viewheight + << defaultviewheight << deltaviewheight << bob << momx @@ -1415,6 +1422,7 @@ void player_s::Serialize (FArchive &arc) << BlendA << accuracy << stamina << LogText; + for (i = 0; i < MAXPLAYERS; i++) arc << frags[i]; for (i = 0; i < NUMPSPRITES; i++) @@ -1472,3 +1480,4 @@ void player_s::Serialize (FArchive &arc) oldbuttons = ~0; } } + diff --git a/src/po_man.cpp b/src/po_man.cpp index 9dd68dc41..6a4b700d4 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -189,12 +189,12 @@ void DRotatePoly::Tick () { unsigned int absSpeed = abs (m_Speed); - if ((unsigned int)m_Dist == ~0u) + if (m_Dist == -1) { // perpetual polyobj return; } m_Dist -= absSpeed; - if (m_Dist == 0) + if (m_Dist <= 0 && m_Dist+absSpeed>0) { polyobj_t *poly = GetPolyobj (m_PolyObj); if (poly->specialdata == this) @@ -471,7 +471,7 @@ void DPolyDoor::Tick () if (PO_RotatePolyobj (m_PolyObj, m_Speed)) { absSpeed = abs (m_Speed); - if (m_Dist == ~0u) + if (m_Dist == -1) { // perpetual polyobj return; } diff --git a/src/r_data.cpp b/src/r_data.cpp index bb14aa57f..a27d26b97 100644 --- a/src/r_data.cpp +++ b/src/r_data.cpp @@ -746,9 +746,10 @@ FTexture::FTexture () : LeftOffset(0), TopOffset(0), WidthBits(0), HeightBits(0), ScaleX(8), ScaleY(8), UseType(TEX_Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false), - bMasked(true), bAlphaTexture(false), bHasCanvas(false), + bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), Rotations(0xFFFF), Width(0xFFFF), Height(0), WidthMask(0) { + *Name=0; } FTexture::~FTexture () @@ -1127,22 +1128,26 @@ const BYTE *FPatchTexture::GetColumn (unsigned int column, const Span **spans_ou void FPatchTexture::GetDimensions () { - FWadLump lump = Wads.OpenLumpNum (SourceLump); + // Wads.OpenLumpNum cannot be used here once Zip support has been added. + // To work correctly it needs an assignment operator which + // would cause considerable overhead elsewhere where it isn't needed. + FWadLump * lump = Wads.ReopenLumpNum (SourceLump); patch_t dummy; - lump >> dummy.width >> dummy.height; + (*lump) >> dummy.width >> dummy.height; if (dummy.width <= 0 || dummy.height <= 0 || dummy.width > 2048 || dummy.height > 2048) { - lump = Wads.OpenLumpName ("-BADPATC"); - lump >> dummy.width >> dummy.height; + lump = Wads.ReopenLumpNum ( Wads.GetNumForName("-BADPATC") ); + (*lump) >> dummy.width >> dummy.height; } - lump >> dummy.leftoffset >> dummy.topoffset; + (*lump) >> dummy.leftoffset >> dummy.topoffset; Width = dummy.width; Height = dummy.height; LeftOffset = dummy.leftoffset; TopOffset = dummy.topoffset; + delete lump; CalcBitSize (); } @@ -1175,10 +1180,13 @@ void FPatchTexture::MakeTexture () Printf (PRINT_BOLD, "Patch %s is too big.\n", Name); } - Width = LittleShort(patch->width); - Height = LittleShort(patch->height); - LeftOffset = LittleShort(patch->leftoffset); - TopOffset = LittleShort(patch->topoffset); + if (Width == 0xFFFF) + { + Width = LittleShort(patch->width); + Height = LittleShort(patch->height); + LeftOffset = LittleShort(patch->leftoffset); + TopOffset = LittleShort(patch->topoffset); + } CalcBitSize (); // Add a little extra space at the end if the texture's height is not @@ -1643,10 +1651,13 @@ void FIMGZTexture::MakeTexture () const ImageHeader *imgz = (const ImageHeader *)lump.GetMem(); const BYTE *data = (const BYTE *)&imgz[1]; - Width = LittleShort(imgz->Width); - Height = LittleShort(imgz->Height); - LeftOffset = LittleShort(imgz->LeftOffset); - TopOffset = LittleShort(imgz->TopOffset); + if (Width != 0xFFFF) + { + Width = LittleShort(imgz->Width); + Height = LittleShort(imgz->Height); + LeftOffset = LittleShort(imgz->LeftOffset); + TopOffset = LittleShort(imgz->TopOffset); + } BYTE *dest_p; int dest_adv = Height; @@ -2331,6 +2342,7 @@ FWarpTexture::FWarpTexture (FTexture *source) ScaleY = source->ScaleY; bNoDecals = source->bNoDecals; Rotations = source->Rotations; + bWarped = 1; } FWarpTexture::~FWarpTexture () @@ -2454,6 +2466,7 @@ void FWarpTexture::MakeTexture (DWORD time) FWarp2Texture::FWarp2Texture (FTexture *source) : FWarpTexture (source) { + bWarped = 2; } void FWarp2Texture::MakeTexture (DWORD time) diff --git a/src/r_defs.h b/src/r_defs.h index 391b3c709..1eddeb4b8 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -365,6 +365,7 @@ struct sector_t FExtraLight *ExtraLights; vertex_t *Triangle[3]; // Three points that can define a plane + short oldspecial; //jff 2/16/98 remembers if sector WAS secret (automap) }; struct ReverbContainer; @@ -385,6 +386,7 @@ enum WALLF_ABSLIGHTING = 1, // Light is absolute instead of relative WALLF_NOAUTODECALS = 2, // Do not attach impact decals to this wall WALLF_ADDTRANS = 4, // Use additive instead of normal translucency + WALLF_AUTOCONTRAST = 8, // Automatically handle fake contrast in side_s::GetLightLevel }; struct side_s @@ -607,6 +609,7 @@ public: BYTE bMasked:1; // Texture (might) have holes BYTE bAlphaTexture:1; // Texture is an alpha channel without color information BYTE bHasCanvas:1; // Texture is based off FCanvasTexture + BYTE bWarped:2; // This is a warped texture. Used to avoid multiple warps on one texture WORD Rotations; diff --git a/src/r_main.cpp b/src/r_main.cpp index 575568edb..c204b3cc2 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -1774,9 +1774,9 @@ void FActiveInterpolation::DoAnInterpolation (fixed_t smoothratio) *adr2 = oldipos[1] + FixedMul (pos - oldipos[1], smoothratio); } -size_t FActiveInterpolation::HashKey (EInterpType type, void *interptr) +unsigned FActiveInterpolation::HashKey (EInterpType type, void *interptr) { - return ((size_t)(interptr))>>5; + return (unsigned)type * ((unsigned)interptr>>5); } int FActiveInterpolation::CountInterpolations () @@ -1823,7 +1823,7 @@ int FActiveInterpolation::CountInterpolations (int *usedbuckets, int *minbucketf FActiveInterpolation *FActiveInterpolation::FindInterpolation (EInterpType type, void *interptr, FActiveInterpolation **&interp_p) { - size_t hash = HashKey (type, interptr) % INTERPOLATION_BUCKETS; + unsigned hash = HashKey (type, interptr) % INTERPOLATION_BUCKETS; FActiveInterpolation *probe, **probe_p; for (probe_p = &curiposhash[hash], probe = *probe_p; diff --git a/src/r_main.h b/src/r_main.h index f15ea0797..99d0aa3ff 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -229,7 +229,7 @@ private: void CopyBakToInterp(); void DoAnInterpolation(fixed_t smoothratio); - static size_t HashKey(EInterpType type, void *interptr); + static unsigned HashKey(EInterpType type, void *interptr); static FActiveInterpolation *FindInterpolation(EInterpType, void *interptr, FActiveInterpolation **&interp_p); friend void updateinterpolations(); diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 926004f8b..aa9d91f7b 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -1066,7 +1066,7 @@ void R_NewWall (bool needlights) int side_s::GetLightLevel (bool foggy, int baselight) const { // [RH] Get wall light level - if (this->Flags & WALLF_ABSLIGHTING) + if (this->Flags & WALLF_ABSLIGHTING && (!(this->Flags & WALLF_AUTOCONTRAST) || foggy)) { return (BYTE)this->Light; } @@ -1074,7 +1074,19 @@ int side_s::GetLightLevel (bool foggy, int baselight) const { if (!foggy) // Don't do relative lighting in foggy sectors { - baselight += this->Light * 2; + int rellight; + + if (this->Flags & WALLF_AUTOCONTRAST) + { + baselight = (BYTE)this->Light; + rellight = linedef->dx==0? level.WallVertLight : linedef->dy==0 ? level.WallHorizLight : 0; + } + else + { + rellight = this->Light; + } + + baselight += rellight * 2; } return baselight; } diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index c4559e1e7..fc1e4294a 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -520,6 +520,47 @@ int S_DupPlayerSound (const char *pclass, int gender, int refid, int aliasref) return S_AddPlayerSoundExisting (pclass, gender, refid, aliasto); } +//========================================================================== +// +// S_ClearSoundData +// +// clears all sound tables +// When we want to allow level specific SNDINFO lumps this has to +// be cleared for each level +//========================================================================== + +static void S_ClearSoundData() +{ + int i; + + S_sfx.Clear(); + + for(i=0;i<256;i++) + { + if (Ambients[i]) delete Ambients[i]; + Ambients[i]=NULL; + } + for(i=0;iNext; + delete me; + } + S_rnd.Clear(); + + DoneReserving=false; + NumPlayerReserves=0; + PlayerClassesIsSorted=false; + PlayerClasses.Clear(); + PlayerSounds.Clear(); + DefPlayerClass=0; + *DefPlayerClassName=0; +} + //========================================================================== // // S_ParseSndInfo @@ -532,6 +573,8 @@ void S_ParseSndInfo () { int lump; + S_ClearSoundData(); // remove old sound data first! + CurrentPitchMask = 0; S_AddSound ("{ no sound }", "DSEMPTY"); // Sound 0 is no sound at all for (lump = 0; lump < Wads.GetNumLumps(); ++lump) @@ -576,6 +619,26 @@ void S_ParseSndInfo () sfx_empty = Wads.CheckNumForName ("dsempty"); } +//========================================================================== +// +// Adds a level specific SNDINFO lump +// +//========================================================================== + +void S_AddLocalSndInfo(int lump) +{ + S_AddSNDINFO(lump); + S_HashSounds (); + S_sfx.ShrinkToFit (); + + if (S_rnd.Size() > 0) + { + S_rnd.ShrinkToFit (); + } + + S_ShrinkPlayerSoundLists (); +} + //========================================================================== // // S_AddSNDINFO diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index 9dbce21f0..f5c10588e 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -369,7 +369,7 @@ static void AssignHexenTranslations (void) // //========================================================================== -void S_ParseSndSeq (void) +void S_ParseSndSeq (int levellump) { int lastlump, lump; char name[MAX_SNDNAME+1]; @@ -377,6 +377,20 @@ void S_ParseSndSeq (void) int cursize; int curseq = -1; + // First free the old SNDSEQ data. This allows us to reload this for each level + // and specify a level specific SNDSEQ lump! + if (Sequences) + { + for (int i=0;i -#include "actor.h" +//#include "actor.h" #include "s_sound.h" #include "r_defs.h" @@ -16,7 +16,7 @@ typedef enum { struct sector_t; -void S_ParseSndSeq (void); +void S_ParseSndSeq (int levellump); void SN_StartSequence (AActor *mobj, int sequence, seqtype_t type); void SN_StartSequence (AActor *mobj, const char *name); void SN_StartSequence (sector_t *sector, int sequence, seqtype_t type); diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 90ea1db9a..b1772c33d 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -50,6 +50,7 @@ #include "vectors.h" #include "gi.h" #include "templates.h" +#include "zstring.h" // MACROS ------------------------------------------------------------------ @@ -264,6 +265,10 @@ void S_NoiseDebug (void) BorderNeedRefresh = screen->GetPageCount (); } +static string LastLocalSndInfo = ""; +static string LastLocalSndSeq = ""; +void S_AddLocalSndInfo(int lump); + //========================================================================== // // S_Init @@ -279,6 +284,10 @@ void S_Init () Printf ("S_Init\n"); + // remove old data (S_Init can be called multiple times!) + LastLocalSndInfo = LastLocalSndSeq = ""; + if (SoundCurve) delete [] SoundCurve; + // Heretic and Hexen have sound curve lookup tables. Doom does not. curvelump = Wads.CheckNumForName ("SNDCURVE"); if (curvelump >= 0) @@ -305,7 +314,7 @@ void S_Init () } // [RH] Read in sound sequences - S_ParseSndSeq (); + S_ParseSndSeq (-1); // Allocating the virtual channels numChannels = GSnd ? GSnd->SetChannels (snd_channels) : 0; @@ -345,13 +354,59 @@ void S_Start () { int cnum; - // kill all playing sounds at start of level (trust me - a good idea) - for (cnum = 0; cnum < numChannels; cnum++) + if (GSnd) { - if (Channel[cnum].sfxinfo) + // kill all playing sounds at start of level (trust me - a good idea) + for (cnum = 0; cnum < numChannels; cnum++) { - S_StopChannel (cnum); + if (Channel[cnum].sfxinfo) + { + S_StopChannel (cnum); + } } + + // Check for local sound definitions. Only reload if they differ + // from the previous ones. + + // To be certain better check whether level is valid! + char * LocalSndInfo= level.info? level.info->soundinfo : (char*)""; + char * LocalSndSeq = level.info? level.info->sndseq : (char*)""; + bool parse_ss=false; + + // This level uses a different local SNDINFO + if (LastLocalSndInfo.CompareNoCase(LocalSndInfo) != 0 || !level.info) + { + // First delete the old sound list + for(unsigned i=1;iUnloadSound(&S_sfx[i]); + } + + // Parse the global SNDINFO + S_ParseSndInfo(); + + if (*LocalSndInfo) + { + // Now parse the local SNDINFO + int j = Wads.CheckNumForName(LocalSndInfo); + if (j>=0) S_AddLocalSndInfo(j); + } + + // Also reload the SNDSEQ if the SNDINFO was replaced! + parse_ss=true; + } + else if (LastLocalSndSeq.CompareNoCase(LocalSndSeq) != 0) + { + parse_ss=true; + } + if (parse_ss) + { + S_ParseSndSeq(*LocalSndSeq? Wads.CheckNumForName(LocalSndSeq) : -1); + } + else + + LastLocalSndInfo = LocalSndInfo; + LastLocalSndSeq = LocalSndSeq; } // start new music for the level diff --git a/src/thingdef.cpp b/src/thingdef.cpp index 132b4d49c..f4aa76122 100644 --- a/src/thingdef.cpp +++ b/src/thingdef.cpp @@ -210,6 +210,8 @@ static flagdef ActorFlags[]= DEFINE_FLAG(MF4, ALLOWPARTICLES, AActor, flags4), DEFINE_FLAG(MF4, EXTREMEDEATH, AActor, flags4), DEFINE_FLAG(MF4, NOEXTREMEDEATH, AActor, flags4), + DEFINE_FLAG(MF4, FRIGHTENED, AActor, flags4), + DEFINE_FLAG(MF4, NOBOUNCESOUND, AActor, flags4), // Effect flags DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), @@ -2665,6 +2667,15 @@ static void ActorBloodColor (AActor *defaults, Baggage &bag) } +//========================================================================== +// +//========================================================================== +static void ActorBounceFactor (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat (); + defaults->bouncefactor = sc_Float * FRACUNIT; +} + //========================================================================== // //========================================================================== @@ -3227,6 +3238,7 @@ static const ActorProps props[] = { "armor.savepercent", (apf)ArmorSavePercent, RUNTIME_CLASS(AActor) }, { "attacksound", ActorAttackSound, RUNTIME_CLASS(AActor) }, { "bloodcolor", ActorBloodColor, RUNTIME_CLASS(AActor) }, + { "bouncefactor", ActorBounceFactor, RUNTIME_CLASS(AActor) }, { "burn", ActorBurnState, RUNTIME_CLASS(AActor) }, { "burnheight", ActorBurnHeight, RUNTIME_CLASS(AActor) }, { "clearflags", ActorClearFlags, RUNTIME_CLASS(AActor) }, @@ -3424,3 +3436,5 @@ void FinishThingdef() } } } + + diff --git a/src/v_font.cpp b/src/v_font.cpp index d66b4e010..240c76c4a 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -358,7 +358,7 @@ int FFont::SimpleTranslation (byte *colorsused, byte *translation, byte *reverse memset (translation, 0, 256); reverse[0] = 0; - for (i = 0, j = 1; i < 256; i++) + for (i = 1, j = 1; i < 256; i++) { if (colorsused[i]) { @@ -384,7 +384,7 @@ int FFont::SimpleTranslation (byte *colorsused, byte *translation, byte *reverse min = (*luminosity)[i]; } diver = 1.0 / (max - min); - for (i = 0; i < j; i++) + for (i = 1; i < j; i++) { (*luminosity)[i] = ((*luminosity)[i] - min) * diver; } @@ -872,6 +872,8 @@ void FSingleLumpFont::BuildTranslations2 () *range++ = ColorMatcher.Pick (r, g, b); } } + // Make CR_UNTRANSLATED a valid translation! + memcpy(range, range-ActiveColors, ActiveColors); } FFontChar1::FFontChar1 (int sourcelump, const BYTE *sourceremap) diff --git a/src/v_video.h b/src/v_video.h index fadbb3595..9528d3f6f 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -155,7 +155,7 @@ public: virtual void Dim (PalEntry color, float amount, int x1, int y1, int w, int h) const; // Fill an area with a texture - void FlatFill (int left, int top, int right, int bottom, FTexture *src); + virtual void FlatFill (int left, int top, int right, int bottom, FTexture *src); // Set an area to a specified color virtual void Clear (int left, int top, int right, int bottom, int color) const; diff --git a/src/version.h b/src/version.h index 88eec9438..412dbab02 100644 --- a/src/version.h +++ b/src/version.h @@ -43,11 +43,13 @@ enum { GAMEVERSION = 205 }; // SAVEVER is the version of the information stored in level snapshots. // Note that SAVEVER is not directly comparable to VERSION. // SAVESIG should match SAVEVER. -#define SAVEVER 230 -#define SAVESIG "ZDOOMSAVE230" +#define SAVEVER 231 +#define SAVESIG "ZDOOMSAVE231" +// This is so that derivates can use the same savegame versions without worrying about engine compatibility +#define GAMESIG "ZDOOM" // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 221 // Used by 2.0.90 +#define MINSAVEVER 231 // Used by 2.0.99 // The maximum length of one save game description for the menus. #define SAVESTRINGSIZE 24 diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index 4668a0156..7ee2f4d1e 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -1265,13 +1265,13 @@ static HRESULT InitJoystick () static void DI_Acquire (LPDIRECTINPUTDEVICE8 mouse) { - mouse->Acquire (); + if (mouse) mouse->Acquire (); SetCursorState (NativeMouse); } static void DI_Unacquire (LPDIRECTINPUTDEVICE8 mouse) { - mouse->Unacquire (); + if (mouse) mouse->Unacquire (); SetCursorState (TRUE); } diff --git a/wadsrc/languages/french.txt b/wadsrc/languages/french.txt index b34f1f386..f4ffd7809 100644 --- a/wadsrc/languages/french.txt +++ b/wadsrc/languages/french.txt @@ -24,7 +24,7 @@ QLPROMPT = "VOULEZ-VOUS CHARGER LA SAUVEGARDE" NEWGAME = "VOUS NE POUVEZ PAS LANCER\n" "UN NOUVEAU JEU SUR RESEAU.\n\nAPPUYEZ SUR UNE TOUCHE."; NIGHTMARE = "VOUS CONFIRMEZ? CE NIVEAU EST\n" - "VRAIMENT IMPITOYABLE!nAPPUYEZ SUR Y OU N"; + "VRAIMENT IMPITOYABLE!\nAPPUYEZ SUR Y OU N"; SWSTRING = "CECI EST UNE VERSION SHAREWARE DE DOOM.\n\n" "VOUS DEVRIEZ COMMANDER LA TRILOGIE COMPLETE.\n\nAPPUYEZ SUR UNE TOUCHE."; MSGOFF = "MESSAGES OFF"; diff --git a/zdoom.vcproj b/zdoom.vcproj index f7d019a08..e9258d6f1 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -692,6 +692,9 @@ AdditionalOptions="" /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" "/> + + + +