From 6362d775ad28e554d04f49c1e2ae70b4b1591904 Mon Sep 17 00:00:00 2001 From: gez Date: Sat, 20 Apr 2013 21:17:54 +0000 Subject: [PATCH] * 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 --- src/actor.h | 2 +- src/d_player.h | 1 + src/g_shared/a_morph.cpp | 3 ++ src/g_shared/a_pickups.cpp | 27 +++++++++++ src/g_shared/a_pickups.h | 1 + src/p_interaction.cpp | 2 +- src/p_mobj.cpp | 9 +--- src/p_user.cpp | 7 +-- src/r_bsp.cpp | 10 ++--- src/r_data/voxels.cpp | 8 ++++ src/r_defs.h | 8 +++- src/r_plane.cpp | 2 +- src/r_segs.cpp | 10 ++--- src/r_things.cpp | 55 ++++++++++++++++------- src/r_things.h | 34 +++++++++----- src/r_utility.cpp | 22 ++++----- src/svnrevision.h | 4 +- src/thingdef/thingdef_data.cpp | 1 + wadsrc/static/actors/shared/inventory.txt | 1 + 19 files changed, 143 insertions(+), 64 deletions(-) diff --git a/src/actor.h b/src/actor.h index 7edf0c6a..12c574d1 100644 --- a/src/actor.h +++ b/src/actor.h @@ -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); diff --git a/src/d_player.h b/src/d_player.h index 48c38744..96fb1399 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -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 }; // diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 58781f05..da4f4691 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -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; } diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 89bfe308..bba5cfdc 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -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 diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index b31d4e28..4be7100a 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -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); diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 51527a26..a61c1b9d 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -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); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index e0dc45ad..9895d7a5 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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())) { diff --git a/src/p_user.cpp b/src/p_user.cpp index 3763cbe4..42031d29 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -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) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 4fe0ef03..9ada2fde 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -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 && diff --git a/src/r_data/voxels.cpp b/src/r_data/voxels.cpp index eca4c89c..69398670 100644 --- a/src/r_data/voxels.cpp +++ b/src/r_data/voxels.cpp @@ -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])) diff --git a/src/r_defs.h b/src/r_defs.h index 88ba3769..a7d63a98 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 16e9b12e..8bf54445 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -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; diff --git a/src/r_segs.cpp b/src/r_segs.cpp index e37cbe08..c4dca60f 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -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; } diff --git a/src/r_things.cpp b/src/r_things.cpp index dae30ae1..276cbd8b 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -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)) diff --git a/src/r_things.h b/src/r_things.h index 92428b63..14ed8afc 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -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); diff --git a/src/r_utility.cpp b/src/r_utility.cpp index b7581103..b5382cca 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -849,15 +849,17 @@ void R_SetupFrame (AActor *actor) TArray &lightlist = viewsector->e->XFloor.lightlist; if (lightlist.Size() > 0) { - for(unsigned int i=0;ifloorplane.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) diff --git a/src/svnrevision.h b/src/svnrevision.h index cc1ab54e..c46dde6d 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -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 diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 68a17241..c542c895 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -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[] = diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 7b2c3d5e..5f5e20b5 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -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" }