mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
Disabled player sprites when crossing through portals.
This commit is contained in:
parent
cf7654bb5a
commit
f647545c1d
7 changed files with 52 additions and 14 deletions
|
@ -375,6 +375,7 @@ public:
|
|||
int chickenPeck = 0; // chicken peck countdown
|
||||
int jumpTics = 0; // delay the next jump for a moment
|
||||
bool onground = 0; // Identifies if this player is on the ground or other object
|
||||
bool crossingPortal = 0; // Crossing a portal (disables sprite from showing up)
|
||||
|
||||
int respawn_time = 0; // [RH] delay respawning until this tic
|
||||
TObjPtr<AActor*> camera = MakeObjPtr<AActor*>(nullptr); // [RH] Whose eyes this player sees through
|
||||
|
|
|
@ -51,6 +51,7 @@ struct FCheckPosition;
|
|||
struct FTranslatedLineTarget;
|
||||
struct FLinePortal;
|
||||
class DViewPosition;
|
||||
struct FRenderViewpoint;
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -396,7 +397,7 @@ void P_PlaySpawnSound(AActor *missile, AActor *spawner);
|
|||
void P_AimCamera (AActor *t1, DVector3 &, DAngle &, sector_t *&sec, bool &unlinked);
|
||||
|
||||
// [MC] Aiming for ViewPos
|
||||
void P_AdjustViewPos(AActor *t1, DVector3 orig, DVector3 &, sector_t *&sec, bool &unlinked, DViewPosition *VP);
|
||||
void P_AdjustViewPos(AActor *t1, DVector3 orig, DVector3 &, sector_t *&sec, bool &unlinked, DViewPosition *VP, FRenderViewpoint *view);
|
||||
|
||||
|
||||
// [RH] Means of death
|
||||
|
|
|
@ -2636,13 +2636,15 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
|
|||
auto p = thing->Level->GetConsolePlayer();
|
||||
if (p) p->viewz += hit.pos.Z; // needs to be done here because otherwise the renderer will not catch the change.
|
||||
P_TranslatePortalAngle(ld, hit.angle);
|
||||
if (thing->player && (port->mType == PORTT_INTERACTIVE || port->mType == PORTT_TELEPORT))
|
||||
thing->player->crossingPortal = true;
|
||||
}
|
||||
R_AddInterpolationPoint(hit);
|
||||
}
|
||||
if (port->mType == PORTT_LINKED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -5600,24 +5602,47 @@ void P_AimCamera(AActor *t1, DVector3 &campos, DAngle &camangle, sector_t *&Came
|
|||
camangle = trace.SrcAngleFromTarget - DAngle::fromDeg(180.);
|
||||
}
|
||||
|
||||
struct ViewPosPortal
|
||||
{
|
||||
int counter;
|
||||
};
|
||||
|
||||
static ETraceStatus VPos_CheckPortal(FTraceResults &res, void *userdata)
|
||||
{
|
||||
//[MC] Mirror how third person works.
|
||||
ViewPosPortal *pc = (ViewPosPortal *)userdata;
|
||||
|
||||
if (res.HitType == TRACE_CrossingPortal)
|
||||
{
|
||||
res.HitType = TRACE_HitNone; // Needed to force the trace to continue appropriately.
|
||||
pc->counter++;
|
||||
return TRACE_Skip;
|
||||
}
|
||||
if (res.HitType == TRACE_HitActor)
|
||||
{
|
||||
return TRACE_Skip;
|
||||
}
|
||||
return TRACE_Stop;
|
||||
}
|
||||
|
||||
// [MC] Used for ViewPos. Uses code borrowed from P_AimCamera.
|
||||
void P_AdjustViewPos(AActor *t1, DVector3 orig, DVector3 &campos, sector_t *&CameraSector, bool &unlinked, DViewPosition *VP)
|
||||
void P_AdjustViewPos(AActor *t1, DVector3 orig, DVector3 &campos, sector_t *&CameraSector, bool &unlinked, DViewPosition *VP, FRenderViewpoint *view)
|
||||
{
|
||||
FTraceResults trace;
|
||||
ViewPosPortal pc;
|
||||
pc.counter = 0;
|
||||
const DVector3 vvec = campos - orig;
|
||||
const double distance = vvec.Length();
|
||||
|
||||
// Trace handles all of the portal crossing, which is why there is no usage of Vec#Offset(Z).
|
||||
if (Trace(orig, t1->Sector, vvec.Unit(), distance, 0, 0, t1, trace) &&
|
||||
if (Trace(orig, CameraSector, vvec.Unit(), distance, 0, 0, t1, trace, TRACE_ReportPortals, VPos_CheckPortal, &pc) &&
|
||||
trace.Distance > 5)
|
||||
{
|
||||
// Position camera slightly in front of hit thing
|
||||
campos = orig + vvec.Unit() * (trace.Distance - 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
campos = trace.HitPos - trace.HitVector * 1 / 256.;
|
||||
}
|
||||
|
||||
|
||||
if (pc.counter > 2) view->noviewer = true;
|
||||
CameraSector = trace.Sector;
|
||||
unlinked = trace.unlinked;
|
||||
}
|
||||
|
|
|
@ -3771,7 +3771,8 @@ void AActor::Tick ()
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (player)
|
||||
player->crossingPortal = false;
|
||||
if (!player || !(player->cheats & CF_PREDICTING))
|
||||
{
|
||||
// Handle powerup effects here so that the order is controlled
|
||||
|
|
|
@ -770,13 +770,23 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Some added checks if the camera actor is not supposed to be seen. It can happen that some portal setup has this actor in view in which case it may not be skipped here
|
||||
if (viewmaster == camera && !vp.showviewer)
|
||||
{
|
||||
if (vp.noviewer || (viewmaster->player && viewmaster->player->crossingPortal)) return;
|
||||
DVector3 vieworigin = viewmaster->Pos();
|
||||
if (thruportal == 1) vieworigin += di->Level->Displacements.getOffset(viewmaster->Sector->PortalGroup, sector->PortalGroup);
|
||||
if (fabs(vieworigin.X - vp.ActorPos.X) < 2 && fabs(vieworigin.Y - vp.ActorPos.Y) < 2) return;
|
||||
|
||||
// Necessary in order to prevent sprite pop-ins with viewpos and models.
|
||||
auto* sec = viewmaster->Sector;
|
||||
if (sec && !sec->PortalBlocksMovement(sector_t::ceiling))
|
||||
{
|
||||
double zh = sec->GetPortalPlaneZ(sector_t::ceiling);
|
||||
double top = (viewmaster->player ? max<double>(viewmaster->player->viewz, viewmaster->Top()) + 1 : viewmaster->Top());
|
||||
if (viewmaster->Z() < zh && top >= zh)
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Thing is invisible if close to the camera.
|
||||
if (viewmaster->renderflags & RF_MAYBEINVISIBLE)
|
||||
|
@ -858,7 +868,6 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!modelframe)
|
||||
{
|
||||
bool mirror = false;
|
||||
|
|
|
@ -600,6 +600,7 @@ void R_InterpolateView (FRenderViewpoint &viewpoint, player_t *player, double Fr
|
|||
else break;
|
||||
}
|
||||
}
|
||||
if (moved) viewpoint.noviewer = true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -947,7 +948,7 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
|
|||
// Interpolation still happens with everything else though and seems to work fine.
|
||||
DefaultDraw = false;
|
||||
viewpoint.NoPortalPath = true;
|
||||
P_AdjustViewPos(mo, orig, next, viewpoint.sector, unlinked, VP);
|
||||
P_AdjustViewPos(mo, orig, next, viewpoint.sector, unlinked, VP, &viewpoint);
|
||||
|
||||
if (viewpoint.sector->PortalGroup != oldsector->PortalGroup || (unlinked && ((iview->New.Pos.XY() - iview->Old.Pos.XY()).LengthSquared()) > 256 * 256))
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@ struct FRenderViewpoint
|
|||
int extralight; // extralight to be added to this viewpoint
|
||||
bool showviewer; // show the camera actor?
|
||||
bool NoPortalPath; // Disable portal interpolation path for actor viewpos.
|
||||
|
||||
bool noviewer; // Force camera sprite off for first person.
|
||||
void SetViewAngle(const FViewWindow &viewwindow);
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue