- 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.


SVN r1668 (trunk)
This commit is contained in:
Christoph Oelckers 2009-06-14 13:47:38 +00:00
parent e69f90076d
commit 3ab370b6ee
16 changed files with 149 additions and 36 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);
//==========================================================================
//

View File

@ -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

View File

@ -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 },

View File

@ -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)

View File

@ -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} },
};

View File

@ -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)

View File

@ -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;
}
};

View File

@ -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) &&

View File

@ -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;
}

View File

@ -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);
}
}
//==========================================================================

View File

@ -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);

View File

@ -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<int> Translation;
int HashFirst[HASH_SIZE];
FTextureID DefaultTexture;
TArray<int> FirstTextureForFile;
};
extern FTextureManager TexMan;

View File

@ -14,6 +14,7 @@ ACTOR Pod 2035
+CANPASS +TELESTOMP +DONTMORPH
+NOBLOCKMONST +DONTGIB +OLDRADIUSDMG
DeathSound "world/podexplode"
PushFactor 0.5
action native A_PodPain (class<Actor> podtype = "PodGoo");
action native A_RemovePod ();