* Updated to ZDoom 4221:

- Dropped items with the DONTGIB flag set will no longer be destroyed by crushers.
- Fixed: Voxel rendering completely fell apart when a mirror came into view. [Software renderer only. OpenGL was and still is fine.]
- Force all voxel mip levels to use the same pivot point as the first level.
- Added DONTGIB flag to Key, so key-dropping enemies can be used reliably near crushers.
- Fixed: When trying to unmorph a monster, make sure the morphed version doesn't have the TOUCHY flag set, or checking the position of the unmorphed version will kill the morphed version, since they will both exist in the same place at the same time, and TOUCHY is really touchy about that.
- Use tests less prone to overflow on very steep slopes when detecting which side of a plane the camera is on. Mostly, this means testing the distance of the camera to the plane rather than computing the plane's Z at the camera and comparing that with the camera's Z. [Software only, OpenGL was and still is fine.]
- Added CROUCHABLEMORPH flag for the PlayerPawn class. Use this to indicate that a morphed player class can crouch. (Regular players can always crouch, hence the name CROUCHABLEMORPH and not CANMORPH or ALLOWMORPH.)

git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1552 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
gez 2013-04-20 21:17:54 +00:00
parent f47e7afed8
commit 6362d775ad
19 changed files with 143 additions and 64 deletions

View file

@ -700,7 +700,7 @@ public:
virtual bool Massacre ();
// Transforms the actor into a finely-ground paste
bool Grind(bool items);
virtual bool Grind(bool items);
// Is the other actor on my team?
bool IsTeammate (AActor *other);

View file

@ -163,6 +163,7 @@ enum
{
PPF_NOTHRUSTWHENINVUL = 1, // Attacks do not thrust the player if they are invulnerable.
PPF_CANSUPERMORPH = 2, // Being remorphed into this class can give you a Tome of Power
PPF_CROUCHABLEMORPH = 4, // This morphed player can crouch
};
//

View file

@ -437,10 +437,13 @@ bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force)
actor->SetOrigin (beast->x, beast->y, beast->z);
actor->flags |= MF_SOLID;
beast->flags &= ~MF_SOLID;
int beastflags6 = beast->flags6;
beast->flags6 &= ~MF6_TOUCHY;
if (!force && !P_TestMobjLocation (actor))
{ // Didn't fit
actor->flags &= ~MF_SOLID;
beast->flags |= MF_SOLID;
beast->flags6 = beastflags6;
beast->UnmorphTime = level.time + 5*TICRATE; // Next try in 5 seconds
return false;
}

View file

@ -515,6 +515,33 @@ void AInventory::BeginPlay ()
flags |= MF_DROPPED; // [RH] Items are dropped by default
}
//===========================================================================
//
// AInventory :: Grind
//
//===========================================================================
bool AInventory::Grind(bool items)
{
// Does this grind request even care about items?
if (!items)
{
return false;
}
// Dropped items are normally destroyed by crushers. Set the DONTGIB flag,
// and they'll act like corpses with it set and be immune to crushers.
if (flags & MF_DROPPED)
{
if (!(flags3 & MF3_DONTGIB))
{
Destroy();
}
return false;
}
// Non-dropped items call the super method for compatibility.
return Super::Grind(items);
}
//===========================================================================
//
// AInventory :: DoEffect

View file

@ -157,6 +157,7 @@ public:
virtual bool SpecialDropAction (AActor *dropper);
virtual bool DrawPowerup (int x, int y);
virtual void DoEffect ();
virtual bool Grind(bool items);
virtual const char *PickupMessage ();
virtual void PlayPickupSound (AActor *toucher);

View file

@ -348,7 +348,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
int realgibhealth = realthis->GibHealth();
if (realthis->health >= realgibhealth)
{
realthis->health = realgibhealth -1; // if morphed was gibbed, so must original be (where allowed)
realthis->health = realgibhealth -1; // if morphed was gibbed, so must original be (where allowed)l
}
}
realthis->Die(source, inflictor, dmgflags);

View file

@ -998,7 +998,7 @@ bool AActor::Grind(bool items)
// ZDoom behavior differs from standard as crushed corpses cannot be raised.
// The reason for the change was originally because of a problem with players,
// see rh_log entry for February 21, 1999. Don't know if it is still relevant.
if (state == NULL // Only use the default crushed state if:
if (state == NULL // Only use the default crushed state if:
&& !(flags & MF_NOBLOOD) // 1. the monster bleeeds,
&& (i_compatflags & COMPATF_CORPSEGIBS) // 2. the compat setting is on,
&& player == NULL) // 3. and the thing isn't a player.
@ -1086,13 +1086,6 @@ bool AActor::Grind(bool items)
return false; // keep checking
}
// crunch dropped items
if (flags & MF_DROPPED)
{
if (items) Destroy (); // Only destroy dropped items if wanted
return false; // keep checking
}
// killough 11/98: kill touchy things immediately
if (flags6 & MF6_TOUCHY && (flags6 & MF6_ARMED || IsSentient()))
{

View file

@ -2204,7 +2204,8 @@ void P_PlayerThink (player_t *player)
{
player->cmd.ucmd.buttons &= ~BT_CROUCH;
}
if (player->morphTics == 0 && player->health > 0 && level.IsCrouchingAllowed())
if ((player->morphTics == 0 || player->mo->PlayerFlags & PPF_CROUCHABLEMORPH)
&& player->health > 0 && level.IsCrouchingAllowed())
{
if (!totallyfrozen)
{
@ -2212,11 +2213,11 @@ void P_PlayerThink (player_t *player)
if (crouchdir == 0)
{
crouchdir = (player->cmd.ucmd.buttons & BT_CROUCH)? -1 : 1;
crouchdir = (player->cmd.ucmd.buttons & BT_CROUCH) ? -1 : 1;
}
else if (player->cmd.ucmd.buttons & BT_CROUCH)
{
player->crouching=0;
player->crouching = 0;
}
if (crouchdir == 1 && player->crouchfactor < FRACUNIT &&
player->mo->z + player->mo->height < player->mo->ceilingz)

View file

@ -346,7 +346,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
{
sector_t *heightsec = viewsector->heightsec;
bool underwater = r_fakingunderwater ||
(heightsec && viewz <= heightsec->floorplane.ZatPoint (viewx, viewy));
(heightsec && heightsec->floorplane.PointOnSide(viewx, viewy, viewz) <= 0);
bool doorunderwater = false;
int diffTex = (s->MoreFlags & SECF_CLIPFAKEPLANES);
@ -405,9 +405,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
}
}
// fixed_t refflorz = s->floorplane.ZatPoint (viewx, viewy);
fixed_t refceilz = s->ceilingplane.ZatPoint (viewx, viewy);
// fixed_t orgflorz = sec->floorplane.ZatPoint (viewx, viewy);
fixed_t orgceilz = sec->ceilingplane.ZatPoint (viewx, viewy);
#if 1
@ -482,7 +480,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
}
FakeSide = FAKED_BelowFloor;
}
else if (heightsec && viewz >= heightsec->ceilingplane.ZatPoint (viewx, viewy) &&
else if (heightsec && heightsec->ceilingplane.PointOnSide(viewx, viewy, viewz) <= 0 &&
orgceilz > refceilz && !(s->MoreFlags & SECF_FAKEFLOORONLY))
{ // Above-ceiling hack
tempsec->ceilingplane = s->ceilingplane;
@ -1084,7 +1082,7 @@ void R_Subsector (subsector_t *sub)
basecolormap = frontsector->ColorMap;
}
ceilingplane = frontsector->ceilingplane.ZatPoint (viewx, viewy) > viewz ||
ceilingplane = frontsector->ceilingplane.PointOnSide(viewx, viewy, viewz) > 0 ||
frontsector->GetTexture(sector_t::ceiling) == skyflatnum ||
(frontsector->CeilingSkyBox != NULL && frontsector->CeilingSkyBox->bAlways) ||
(frontsector->heightsec &&
@ -1123,7 +1121,7 @@ void R_Subsector (subsector_t *sub)
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
// killough 3/16/98: add floorlightlevel
// killough 10/98: add support for skies transferred from sidedefs
floorplane = frontsector->floorplane.ZatPoint (viewx, viewy) < viewz || // killough 3/7/98
floorplane = frontsector->floorplane.PointOnSide(viewx, viewy, viewz) > 0 || // killough 3/7/98
frontsector->GetTexture(sector_t::floor) == skyflatnum ||
(frontsector->FloorSkyBox != NULL && frontsector->FloorSkyBox->bAlways) ||
(frontsector->heightsec &&

View file

@ -296,6 +296,14 @@ FVoxel *R_LoadKVX(int lumpnum)
}
voxel->NumMips = mip;
// Fix pivot data for submips, since some tools seem to like to just center these.
for (i = 1; i < mip; ++i)
{
voxel->Mips[i].PivotX = voxel->Mips[0].PivotX >> i;
voxel->Mips[i].PivotY = voxel->Mips[0].PivotY >> i;
voxel->Mips[i].PivotZ = voxel->Mips[0].PivotZ >> i;
}
for (i = 0; i < mip; ++i)
{
if (!CopyVoxelSlabs((kvxslab_t *)voxel->Mips[i].SlabData, slabs[i], voxel->Mips[i].OffsetX[voxel->Mips[i].SizeX]))

View file

@ -242,10 +242,16 @@ struct secplane_t
fixed_t a, b, c, d, ic;
// Returns < 0 : behind; == 0 : on; > 0 : in front
int PointOnSide (fixed_t x, fixed_t y, fixed_t z) const
{
return TMulScale16(a,x, b,y, c,z) + d;
}
// Returns the value of z at (0,0) This is used by the 3D floor code which does not handle slopes
fixed_t Zat0 () const
{
return ic < 0? d:-d;
return ic < 0 ? d : -d;
}
// Returns the value of z at (x,y)

View file

@ -1697,7 +1697,7 @@ void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
plane_sz[0] = -plane_sz[0];
}
planelightfloat = (r_TiltVisibility * lxscale * lyscale) / (float)(abs(pl->height.ZatPoint (viewx, viewy) - viewz));
planelightfloat = (r_TiltVisibility * lxscale * lyscale) / (fabs(pl->height.ZatPoint(FIXED2DBL(viewx), FIXED2DBL(viewy)) - FIXED2DBL(viewz))) / 65536.0;
if (pl->height.c > 0)
planelightfloat = -planelightfloat;

View file

@ -2242,10 +2242,10 @@ void R_NewWall (bool needlights)
// killough 3/7/98: add deep water check
if (frontsector->GetHeightSec() == NULL)
{
if (frontsector->floorplane.ZatPoint (viewx, viewy) >= viewz) // above view plane
if (frontsector->floorplane.PointOnSide(viewx, viewy, viewz) <= 0) // above view plane
markfloor = false;
if (frontsector->ceilingplane.ZatPoint (viewx, viewy) <= viewz &&
frontsector->GetTexture(sector_t::ceiling) != skyflatnum) // below view plane
if (frontsector->ceilingplane.PointOnSide(viewx, viewy, viewz) <= 0 &&
frontsector->GetTexture(sector_t::ceiling) != skyflatnum) // below view plane
markceiling = false;
}
@ -2394,13 +2394,13 @@ void R_StoreWallRange (int start, int stop)
ds_p->silhouette = 0;
if (rw_frontfz1 > rw_backfz1 || rw_frontfz2 > rw_backfz2 ||
backsector->floorplane.ZatPoint (viewx, viewy) > viewz)
backsector->floorplane.PointOnSide(viewx, viewy, viewz) < 0)
{
ds_p->silhouette = SIL_BOTTOM;
}
if (rw_frontcz1 < rw_backcz1 || rw_frontcz2 < rw_backcz2 ||
backsector->ceilingplane.ZatPoint (viewx, viewy) < viewz)
backsector->ceilingplane.PointOnSide(viewx, viewy, viewz) < 0)
{
ds_p->silhouette |= SIL_TOP;
}

View file

@ -424,13 +424,18 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop
{
R_CheckOffscreenBuffer(RenderTarget->GetWidth(), RenderTarget->GetHeight(), !!(flags & DVF_SPANSONLY));
}
if (spr->bInMirror)
{
flags |= DVF_MIRRORED;
}
// Render the voxel, either directly to the screen or offscreen.
R_DrawVoxel(spr->gx, spr->gy, spr->gz, spr->angle, spr->xscale, spr->yscale, spr->voxel, spr->Style.colormap, cliptop, clipbot,
R_DrawVoxel(spr->vx, spr->vy, spr->vz, spr->vang, spr->gx, spr->gy, spr->gz, spr->angle,
spr->xscale, spr->yscale, spr->voxel, spr->Style.colormap, cliptop, clipbot,
minslabz, maxslabz, flags);
// Blend the voxel, if that's what we need to do.
if (flags != 0)
if ((flags & ~DVF_MIRRORED) != 0)
{
for (int x = 0; x < viewwidth; ++x)
{
@ -760,10 +765,10 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
vis->angle -= angle_t(ang * (4294967296.f / 360));
}
// These are irrelevant for voxels.
vis->texturemid = 0x1CEDBEEF;
vis->startfrac = 0x1CEDBEEF;
vis->xiscale = 0x1CEDBEEF;
vis->vx = viewx;
vis->vy = viewy;
vis->vz = viewz;
vis->vang = viewangle;
}
// killough 3/27/98: save sector for special clipping later
@ -787,6 +792,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
vis->fakefloor = fakefloor;
vis->fakeceiling = fakeceiling;
vis->ColormapNum = 0;
vis->bInMirror = MirrorFlags & RF_XFLIP;
if (voxel != NULL)
{
@ -1897,6 +1903,16 @@ void R_DrawSprite (vissprite_t *spr)
return;
}
}
// Add everything outside the left and right edges to the clipping array
// for R_DrawVisVoxel().
if (x1 > 0)
{
clearbufshort(cliptop, x1, viewheight);
}
if (x2 < viewwidth - 1)
{
clearbufshort(cliptop + x2 + 1, viewwidth - x2 - 1, viewheight);
}
int minvoxely = spr->gzt <= hzt ? 0 : (spr->gzt - hzt) / spr->yscale;
int maxvoxely = spr->gzb > hzb ? INT_MAX : (spr->gzt - hzb) / spr->yscale;
R_DrawVisVoxel(spr, minvoxely, maxvoxely, cliptop, clipbot);
@ -2228,7 +2244,8 @@ void R_DrawParticle (vissprite_t *vis)
extern fixed_t baseyaspectmul;
void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang,
void R_DrawVoxel(fixed_t globalposx, fixed_t globalposy, fixed_t globalposz, angle_t viewang,
fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang,
fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj,
lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags)
{
@ -2244,12 +2261,14 @@ void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t daspran
const int nytooclose = centerxwide * 2100, nytoofar = 32768*32768 - 1048576;
const int xdimenscale = Scale(centerxwide, yaspectmul, 160);
const fixed_t globalposx = viewx >> 12;
const fixed_t globalposy = -viewy >> 12;
const fixed_t globalposz = -viewz >> 8;
const double centerxwide_f = centerxwide;
const double centerxwidebig_f = centerxwide_f * 65536*65536*8;
// Convert to Build's coordinate system.
globalposx = globalposx >> 12;
globalposy = -globalposy >> 12;
globalposz = -globalposz >> 8;
dasprx = dasprx >> 12;
daspry = -daspry >> 12;
dasprz = -dasprz >> 8;
@ -2259,20 +2278,19 @@ void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t daspran
daxscale = daxscale / (0xC000 >> 6);
dayscale = dayscale / (0xC000 >> 6);
cosang = viewcos >> 2;
sinang = -viewsin >> 2;
cosang = finecosine[viewang >> ANGLETOFINESHIFT] >> 2;
sinang = -finesine[viewang >> ANGLETOFINESHIFT] >> 2;
sprcosang = finecosine[dasprang >> ANGLETOFINESHIFT] >> 2;
sprsinang = -finesine[dasprang >> ANGLETOFINESHIFT] >> 2;
R_SetupDrawSlab(colormap);
// Select mip level
i = abs(DMulScale8(dasprx - globalposx, viewcos, daspry - globalposy, -viewsin));
i = abs(DMulScale6(dasprx - globalposx, cosang, daspry - globalposy, sinang));
i = DivScale6(i, MIN(daxscale, dayscale));
j = FocalLengthX >> 3;
for (k = 0; k < voxobj->NumMips; ++k)
for (k = 0; i >= j && k < voxobj->NumMips; ++k)
{
if (i < j) { break; }
i >>= 1;
}
if (k >= voxobj->NumMips) k = voxobj->NumMips - 1;
@ -2404,6 +2422,13 @@ void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t daspran
if (rx > viewwidth) rx = viewwidth;
if (rx <= lx) continue;
if (flags & DVF_MIRRORED)
{
int t = viewwidth - lx;
lx = viewwidth - rx;
rx = t;
}
fixed_t l1 = xs_RoundToInt(centerxwidebig_f / (ny - yoff));
fixed_t l2 = xs_RoundToInt(centerxwidebig_f / (ny + yoff));
for (; voxptr < voxend; voxptr = (kvxslab_t *)((BYTE *)voxptr + voxptr->zleng + 3))

View file

@ -35,25 +35,36 @@ struct vissprite_t
fixed_t gx, gy, gz; // origin in world coordinates
angle_t angle;
fixed_t gzb, gzt; // global bottom / top for silhouette clipping
fixed_t startfrac; // horizontal position of x1
fixed_t xscale, yscale;
fixed_t xiscale; // negative if flipped
fixed_t depth;
fixed_t idepth; // 1/z
fixed_t texturemid;
DWORD FillColor;
fixed_t floorclip;
union
{
// Used by regular sprites
struct
{
FTexture *pic;
fixed_t texturemid;
fixed_t startfrac; // horizontal position of x1
fixed_t xiscale; // negative if flipped
};
// Used by voxels
struct
{
struct FVoxel *voxel;
fixed_t vx, vy, vz; // view origin
angle_t vang; // view angle
};
};
sector_t *heightsec; // killough 3/27/98: height sector for underwater/fake ceiling
sector_t *sector; // [RH] sector this sprite is in
F3DFloor *fakefloor;
F3DFloor *fakeceiling;
fixed_t floorclip;
union
{
FTexture *pic;
struct FVoxel *voxel;
};
BYTE bIsVoxel:1; // [RH] Use voxel instead of pic
BYTE bSplitSprite:1; // [RH] Sprite was split by a drawseg
BYTE bInMirror:1; // [RH] Sprite is "inside" a mirror
BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on
BYTE ColormapNum; // Which colormap is rendered (needed for shaded drawer)
short renderflags;
@ -102,9 +113,10 @@ void R_DrawRemainingPlayerSprites ();
void R_CheckOffscreenBuffer(int width, int height, bool spansonly);
enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2 };
enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4 };
void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang,
void R_DrawVoxel(fixed_t viewx, fixed_t viewy, fixed_t viewz, angle_t viewangle,
fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang,
fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj,
lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags);

View file

@ -849,15 +849,17 @@ void R_SetupFrame (AActor *actor)
TArray<lightlist_t> &lightlist = viewsector->e->XFloor.lightlist;
if (lightlist.Size() > 0)
{
for(unsigned int i=0;i<lightlist.Size();i++)
for(unsigned int i = 0; i < lightlist.Size(); i++)
{
fixed_t lightbottom;
if (i<lightlist.Size()-1)
lightbottom = lightlist[i+1].plane.ZatPoint(viewx, viewy);
else
lightbottom = viewsector->floorplane.ZatPoint(viewx, viewy);
if (lightbottom < viewz)
secplane_t *plane;
int viewside;
plane = (i < lightlist.Size()-1) ? &lightlist[i+1].plane : &viewsector->floorplane;
viewside = plane->PointOnSide(viewx, viewy, viewz);
// Reverse the direction of the test if the plane was downward facing.
// We want to know if the view is above it, whatever its orientation may be.
if (plane->c < 0)
viewside = -viewside;
if (viewside > 0)
{
// 3d floor 'fog' is rendered as a blending value
PalEntry blendv = lightlist[i].blend;
@ -874,9 +876,9 @@ void R_SetupFrame (AActor *actor)
const sector_t *s = viewsector->GetHeightSec();
if (s != NULL)
{
newblend = viewz < s->floorplane.ZatPoint (viewx, viewy)
newblend = s->floorplane.PointOnSide(viewx, viewy, viewz) < 0
? s->bottommap
: viewz > s->ceilingplane.ZatPoint (viewx, viewy)
: s->ceilingplane.PointOnSide(viewx, viewy, viewz) < 0
? s->topmap
: s->midmap;
if (APART(newblend) == 0 && newblend >= numfakecmaps)

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "4214"
#define ZD_SVN_REVISION_NUMBER 4214
#define ZD_SVN_REVISION_STRING "4221"
#define ZD_SVN_REVISION_NUMBER 4221

View file

@ -336,6 +336,7 @@ static FFlagDef PlayerPawnFlags[] =
// PlayerPawn flags
DEFINE_FLAG(PPF, NOTHRUSTWHENINVUL, APlayerPawn, PlayerFlags),
DEFINE_FLAG(PPF, CANSUPERMORPH, APlayerPawn, PlayerFlags),
DEFINE_FLAG(PPF, CROUCHABLEMORPH, APlayerPawn, PlayerFlags),
};
static FFlagDef PowerSpeedFlags[] =

View file

@ -142,6 +142,7 @@ Actor HealthPickup : Inventory native
Actor Key : Inventory native
{
+DONTGIB // Don't disappear due to a crusher
+INVENTORY.INTERHUBSTRIP
Inventory.PickupSound "misc/k_pkup"
}