diff --git a/docs/rh-log.txt b/docs/rh-log.txt index b4fe91dce..79e5aef52 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,20 @@ -June 10, 2009 +June 14, 2009 (Changes by Graf Zahl) +- added a compatibility option to restore the original Heretic bug where + a Minotaur couldn't spawn floor flames when standing in water having its + feet clipped. +- added vid_vsync to display options. +- fixed: Animations of type 'Range' must be disabled if the textures don't + come from the same definition unit (i.e both containing file and use type + are identical.) +- changed: Item pushing is now only done once per P_XYMovement call. +- Increased the push factor of Heretic's pod to 0.5 so that its behavior + more closely matches the original which depended on several bugs in the engine. +- Removed damage thrust clamping in P_DamageMobj and changed the thrust calculation + to use floats to prevent overflows. The prevention of the overflows was the + only reason the clamping was done. +- Added Raven's dagger-like vector sprite for the player to the automap code. + +June 10, 2009 - Changed wad namespacing so that wads with a missing end marker will be loaded as if they had one more lump with that end marker. This matches the behaviour of previously released ZDooms. (The warning is still present, so diff --git a/src/actor.h b/src/actor.h index d36fe321a..6e6ff0577 100644 --- a/src/actor.h +++ b/src/actor.h @@ -740,6 +740,7 @@ public: fixed_t gravity; // [GRB] Gravity factor int FastChaseStrafeCount; fixed_t pushfactor; + int lastpush; AActor *BlockingMobj; // Actor that blocked the last move line_t *BlockingLine; // Line that blocked the last move diff --git a/src/am_map.cpp b/src/am_map.cpp index 141497e94..1139a4124 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -35,6 +35,7 @@ #include "statnums.h" #include "r_translate.h" #include "d_event.h" +#include "gi.h" #include "m_cheat.h" #include "i_system.h" @@ -251,8 +252,23 @@ mline_t player_arrow[] = { { { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>---> { { -R+3*R/8, 0 }, { -R+R/8, -R/4 } } }; + +mline_t player_arrow_raven[] = { + { { -R+R/4, 0 }, { 0, 0} }, // center line. + { { -R+R/4, R/8 }, { R, 0} }, // blade + { { -R+R/4, -R/8 }, { R, 0 } }, + { { -R+R/4, -R/4 }, { -R+R/4, R/4 } }, // crosspiece + { { -R+R/8, -R/4 }, { -R+R/8, R/4 } }, + { { -R+R/8, -R/4 }, { -R+R/4, -R/4} }, //crosspiece connectors + { { -R+R/8, R/4 }, { -R+R/4, R/4} }, + { { -R-R/4, R/8 }, { -R-R/4, -R/8 } }, //pommel + { { -R-R/4, R/8 }, { -R+R/8, R/8 } }, + { { -R-R/4, -R/8}, { -R+R/8, -R/8 } } + }; + #undef R #define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t)) +#define NUMPLYRLINES_RAVEN (sizeof(player_arrow_raven)/sizeof(mline_t)) #define R ((8*PLAYERRADIUS)/7) mline_t cheat_player_arrow[] = { @@ -273,6 +289,7 @@ mline_t cheat_player_arrow[] = { { { R/6, -R/7 }, { R/6+R/32, -R/7-R/32 } }, { { R/6+R/32, -R/7-R/32 }, { R/6+R/10, -R/7 } } }; + #undef R #define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t)) @@ -1632,7 +1649,13 @@ void AM_drawPlayers () { angle = players[consoleplayer].camera->angle; } - if (am_cheat != 0) + + if (gameinfo.gametype & GAME_Raven) + { + arrow = player_arrow_raven; + numarrowlines = NUMPLYRLINES_RAVEN; + } + else if (am_cheat != 0) { arrow = cheat_player_arrow; numarrowlines = NUMCHEATPLYRLINES; diff --git a/src/d_main.cpp b/src/d_main.cpp index cc78ccb52..1a9a95506 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -491,6 +491,7 @@ CVAR (Flag, compat_sectorsounds,compatflags, COMPATF_SECTORSOUNDS); CVAR (Flag, compat_missileclip, compatflags, COMPATF_MISSILECLIP); CVAR (Flag, compat_crossdropoff,compatflags, COMPATF_CROSSDROPOFF); CVAR (Flag, compat_anybossdeath,compatflags, COMPATF_ANYBOSSDEATH); +CVAR (Flag, compat_minotaur, compatflags, COMPATF_MINOTAUR); //========================================================================== // diff --git a/src/doomdef.h b/src/doomdef.h index 8fa587a11..479fbc5f4 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -271,6 +271,7 @@ enum COMPATF_MISSILECLIP = 1 << 19, // Use original Doom heights for clipping against projectiles COMPATF_CROSSDROPOFF = 1 << 20, // monsters can't be pushed over dropoffs COMPATF_ANYBOSSDEATH = 1 << 21, // [GZ] Any monster which calls BOSSDEATH counts for level specials + COMPATF_MINOTAUR = 1 << 22, // Minotaur's floor flame is exploded immediately when feet are clipped }; // Emulate old bugs for select maps. These are not exposed by a cvar diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 1a57c8c30..10694c0db 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1337,6 +1337,7 @@ MapFlagHandlers[] = { "compat_sectorsounds", MITYPE_COMPATFLAG, COMPATF_SECTORSOUNDS}, { "compat_missileclip", MITYPE_COMPATFLAG, COMPATF_MISSILECLIP}, { "compat_crossdropoff", MITYPE_COMPATFLAG, COMPATF_CROSSDROPOFF}, + { "compat_minotaur", MITYPE_COMPATFLAG, COMPATF_MINOTAUR}, { "cd_start_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end1_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end2_track", MITYPE_EATNEXT, 0, 0 }, diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index c3d6463cc..e4b09a228 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -379,10 +379,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3) } else { - mo = P_SpawnMissile (self, self->target, PClass::FindClass("MinotaurFX2")); - if (mo != NULL) + if (self->floorclip > 0 && (i_compatflags & COMPATF_MINOTAUR)) { - S_Sound (mo, CHAN_WEAPON, "minotaur/attack1", 1, ATTN_NORM); + // only play the sound. + S_Sound (mo, CHAN_WEAPON, "minotaur/fx2hit", 1, ATTN_NORM); + } + else + { + mo = P_SpawnMissile (self, self->target, PClass::FindClass("MinotaurFX2")); + if (mo != NULL) + { + S_Sound (mo, CHAN_WEAPON, "minotaur/attack1", 1, ATTN_NORM); + } } } if (pr_minotauratk3() < 192 && self->special2 == 0) diff --git a/src/m_options.cpp b/src/m_options.cpp index b5efc5ce5..53cc3f670 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -89,6 +89,7 @@ EXTERN_CVAR(Bool, nomonsterinterpolation) EXTERN_CVAR(Int, showendoom) EXTERN_CVAR(Bool, hud_althud) EXTERN_CVAR(Int, compatmode) +EXTERN_CVAR (Bool, vid_vsync) // // defaulted values // @@ -523,6 +524,7 @@ static menuitem_t VideoItems[] = { { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { slider, "Screen size", {&screenblocks}, {3.0}, {12.0}, {1.0}, {NULL} }, { slider, "Brightness", {&Gamma}, {1.0}, {3.0}, {0.1f}, {NULL} }, + { discrete, "Vertical Sync", {&vid_vsync}, {2.0}, {0.0}, {0.0}, {OnOff} }, { discretes,"Crosshair", {&crosshair}, {8.0}, {0.0}, {0.0}, {NULL} }, { discrete, "Column render mode", {&r_columnmethod}, {2.0}, {0.0}, {0.0}, {ColumnMethods} }, { discrete, "Stretch short skies", {&r_stretchsky}, {2.0}, {0.0}, {0.0}, {OnOff} }, @@ -541,7 +543,7 @@ static menuitem_t VideoItems[] = { { discrete, "Bullet Puff Type", {&cl_pufftype}, {2.0}, {0.0}, {0.0}, {PuffTypes} }, }; -#define CROSSHAIR_INDEX 6 +#define CROSSHAIR_INDEX 7 menu_t VideoMenu = { @@ -1143,7 +1145,8 @@ static menuitem_t CompatibilityItems[] = { { bitflag, "Inst. moving floors are not silent", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SILENT_INSTANT_FLOORS} }, { bitflag, "Sector sounds use center as source", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SECTORSOUNDS} }, { bitflag, "Use Doom heights for missile clipping", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_MISSILECLIP} }, - { bitflag, "Allow any bossdeath for level special", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_ANYBOSSDEATH} }, + { bitflag, "Allow any bossdeath for level special", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_ANYBOSSDEATH} }, + { bitflag, "No Minotaur floor flames in water", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_MINOTAUR} }, { discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} }, }; diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index a05ff314e..188b824a6 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1039,12 +1039,20 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage ang = R_PointToAngle2 (origin->x, origin->y, target->x, target->y); - thrust = damage*(FRACUNIT>>3)*kickback / target->Mass; + + + // Calculate this as float to avoid overflows so that the + // clamping that had to be done here can be removed. + thrust = FLOAT2FIXED((damage * 0.125 * kickback) / target->Mass); + // [RH] If thrust overflows, use a more reasonable amount + /* old fixed point code that could overflow. + thrust = damage*(FRACUNIT>>3)*kickback / target->Mass; if (thrust < 0 || thrust > 10*FRACUNIT) { thrust = 10*FRACUNIT; } + */ // make fall forwards sometimes if ((damage < 40) && (damage > target->health) && (target->z - origin->z > 64*FRACUNIT) diff --git a/src/p_local.h b/src/p_local.h index d0cae7f4e..31c554e6c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -350,11 +350,13 @@ struct FCheckPosition // ripping damage once per tic instead of once per move. bool DoRipping; AActor *LastRipped; + int PushTime; FCheckPosition(bool rip=false) { DoRipping = rip; LastRipped = NULL; + PushTime = 0; } }; diff --git a/src/p_map.cpp b/src/p_map.cpp index f89282674..689763ba3 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1008,8 +1008,12 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH)) { // Push thing - thing->momx += tm.thing->momx>>2; - thing->momy += tm.thing->momy>>2; + if (thing->lastpush != tm.PushTime) + { + thing->momx += FixedMul(tm.thing->momx, thing->pushfactor); + thing->momy += FixedMul(tm.thing->momy, thing->pushfactor); + thing->lastpush = tm.PushTime; + } } } spechit.Clear (); @@ -1048,8 +1052,12 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH) && (tm.thing->player == NULL || !(tm.thing->player->cheats & CF_PREDICTING))) { // Push thing - thing->momx += FixedMul(tm.thing->momx, thing->pushfactor); - thing->momy += FixedMul(tm.thing->momy, thing->pushfactor); + if (thing->lastpush != tm.PushTime) + { + thing->momx += FixedMul(tm.thing->momx, thing->pushfactor); + thing->momy += FixedMul(tm.thing->momy, thing->pushfactor); + thing->lastpush = tm.PushTime; + } } solid = (thing->flags & MF_SOLID) && !(thing->flags & MF_NOCLIP) && diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 458997b61..41f6b5289 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1497,6 +1497,7 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax) fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { + static int pushtime = 0; bool bForceSlide = scrollx || scrolly; angle_t angle; fixed_t ptryx, ptryy; @@ -1656,11 +1657,16 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) // last actor ripped through is recorded so that if the projectile // passes through more than one actor this tic, each one takes damage // and not just the first one. + pushtime++; FCheckPosition tm(!!(mo->flags2 & MF2_RIP)); + do { + if (i_compatflags & COMPATF_WALLRUN) pushtime++; + tm.PushTime = pushtime; + ptryx = startx + Scale (xmove, step, steps); ptryy = starty + Scale (ymove, step, steps); @@ -1720,7 +1726,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) fixed_t tx, ty; tx = 0, ty = onestepy; walkplane = P_CheckSlopeWalk (mo, tx, ty); - if (P_TryMove (mo, mo->x + tx, mo->y + ty, true, walkplane)) + if (P_TryMove (mo, mo->x + tx, mo->y + ty, true, walkplane, tm)) { mo->momx = 0; } @@ -1728,7 +1734,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { tx = onestepx, ty = 0; walkplane = P_CheckSlopeWalk (mo, tx, ty); - if (P_TryMove (mo, mo->x + tx, mo->y + ty, true, walkplane)) + if (P_TryMove (mo, mo->x + tx, mo->y + ty, true, walkplane, tm)) { mo->momy = 0; } diff --git a/src/r_anim.cpp b/src/r_anim.cpp index f3a9d67db..22c85c50d 100644 --- a/src/r_anim.cpp +++ b/src/r_anim.cpp @@ -199,18 +199,6 @@ void R_InitPicAnims (void) tex2->Name, pic2.GetIndex(), tex2->GetSourceLump(), Wads.GetLumpFile(tex2->GetSourceLump())); } - /* FIXME: doesn't work with hires texture replacements. - int l1 = tex1->GetSourceLump(); - int l2 = tex2->GetSourceLump(); - - if (tex1->UseType == FTexture::TEX_Wall && l1 != l2) - { - // Animated walls must be in the same definition lumo - continue; - } - */ - - // [RH] Allow for backward animations as well as forward. if (pic1 > pic2) { @@ -244,16 +232,19 @@ void R_InitPicAnims (void) void R_AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD speedmin, DWORD speedrange) { - FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef)); - anim->CurFrame = 0; - anim->BasePic = picnum; - anim->NumFrames = animcount; - anim->AnimType = animtype; - anim->SwitchTime = 0; - anim->Frames[0].SpeedMin = speedmin; - anim->Frames[0].SpeedRange = speedrange; - anim->Frames[0].FramePic = anim->BasePic; - Anims.AddAnim (anim); + if (TexMan.AreTexturesCompatible(picnum, picnum + (animcount - 1))) + { + FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef)); + anim->CurFrame = 0; + anim->BasePic = picnum; + anim->NumFrames = animcount; + anim->AnimType = animtype; + anim->SwitchTime = 0; + anim->Frames[0].SpeedMin = speedmin; + anim->Frames[0].SpeedRange = speedrange; + anim->Frames[0].FramePic = anim->BasePic; + Anims.AddAnim (anim); + } } //========================================================================== diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 12f9412ea..7a66a7202 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -371,6 +371,40 @@ void FTextureManager::ReplaceTexture (FTextureID picnum, FTexture *newtexture, b } } +//========================================================================== +// +// FTextureManager :: AreTexturesCompatible +// +// Checks if 2 textures are compatible for a ranged animation +// +//========================================================================== + +bool FTextureManager::AreTexturesCompatible (FTextureID picnum1, FTextureID picnum2) +{ + int index1 = picnum1.GetIndex(); + int index2 = picnum2.GetIndex(); + if (unsigned(index1) >= Textures.Size() || unsigned(index2) >= Textures.Size()) + return false; + + FTexture *texture1 = Textures[index1].Texture; + FTexture *texture2 = Textures[index2].Texture; + + // both textures must be the same type. + if (texture1 == NULL || texture2 == NULL || texture1->UseType != texture2->UseType) + return false; + + // both textures must be from the same file + for(unsigned i = 0; i < FirstTextureForFile.Size() - 1; i++) + { + if (index1 >= FirstTextureForFile[i] && index1 < FirstTextureForFile[i+1]) + { + return (index2 >= FirstTextureForFile[i] && index2 < FirstTextureForFile[i+1]); + } + } + return false; +} + + //========================================================================== // // FTextureManager :: AddGroup @@ -707,6 +741,8 @@ void FTextureManager::AddTexturesForWad(int wadnum) int firsttexture = Textures.Size(); int lumpcount = Wads.GetNumLumps(); + FirstTextureForFile.Push(firsttexture); + // First step: Load sprites AddGroup(wadnum, ns_sprites, FTexture::TEX_Sprite); @@ -857,7 +893,12 @@ void FTextureManager::Init() { AddTexturesForWad(i); } + + // Add one marker so that the last WAD is easier to handle and treat + // Build tiles as a completely separate block. + FirstTextureForFile.Push(Textures.Size()); R_InitBuildTiles (); + FirstTextureForFile.Push(Textures.Size()); DefaultTexture = CheckForTexture ("-NOFLAT-", FTexture::TEX_Override, 0); diff --git a/src/textures/textures.h b/src/textures/textures.h index f74e438fb..664970036 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -307,6 +307,7 @@ public: void LoadTextureDefs(int wadnum, const char *lumpname); void ParseXTexture(FScanner &sc, int usetype); void SortTexturesByType(int start, int end); + bool AreTexturesCompatible (FTextureID picnum1, FTextureID picnum2); FTextureID CreateTexture (int lumpnum, int usetype=FTexture::TEX_Any); // Also calls AddTexture FTextureID AddTexture (FTexture *texture); @@ -344,6 +345,7 @@ private: TArray Translation; int HashFirst[HASH_SIZE]; FTextureID DefaultTexture; + TArray FirstTextureForFile; }; extern FTextureManager TexMan; diff --git a/wadsrc/static/actors/heretic/hereticmisc.txt b/wadsrc/static/actors/heretic/hereticmisc.txt index a11a984a7..b41a2d4f7 100644 --- a/wadsrc/static/actors/heretic/hereticmisc.txt +++ b/wadsrc/static/actors/heretic/hereticmisc.txt @@ -14,6 +14,7 @@ ACTOR Pod 2035 +CANPASS +TELESTOMP +DONTMORPH +NOBLOCKMONST +DONTGIB +OLDRADIUSDMG DeathSound "world/podexplode" + PushFactor 0.5 action native A_PodPain (class podtype = "PodGoo"); action native A_RemovePod ();