diff --git a/src/actor.h b/src/actor.h index ffe3cc1a4..439ae2644 100644 --- a/src/actor.h +++ b/src/actor.h @@ -418,6 +418,7 @@ enum ActorRenderFlag RF_FLATSPRITE = 0x2000, // Flat sprite RF_VOXELSPRITE = 0x3000, // Voxel object RF_INVISIBLE = 0x8000, // Don't bother drawing this actor + RF_MAYBEINVISIBLE = 0x10000, RF_ROLLSPRITE = 0x40000, //[marrub]roll the sprite billboard RF_DONTFLIP = 0x80000, // Don't flip it when viewed from behind. RF_ROLLCENTER = 0x00100000, // Rotate from the center of sprite instead of offsets diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index e1fed484a..4cf8b9e7b 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -288,7 +288,9 @@ bool GLPortal::Start(bool usestencil, bool doquery) savedAngle = ViewAngle; savedviewactor=GLRenderer->mViewActor; savedviewarea=in_area; - savedvisibility = camera ? camera->renderflags & RF_INVISIBLE : ActorRenderFlags::FromInt(0); + savedviewpath[0] = ViewPath[0]; + savedviewpath[1] = ViewPath[1]; + savedvisibility = camera ? camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0); PrevPortal = GLRenderer->mCurrentPortal; @@ -350,13 +352,15 @@ void GLPortal::End(bool usestencil) if (needdepth) FDrawInfo::EndDrawInfo(); // Restore the old view + ViewPath[0] = savedviewpath[0]; + ViewPath[1] = savedviewpath[1]; ViewPos = savedViewPos; r_showviewer = savedshowviewer; ViewActorPos = savedViewActorPos; ViewAngle = savedAngle; GLRenderer->mViewActor=savedviewactor; in_area=savedviewarea; - if (camera != nullptr) camera->renderflags = (camera->renderflags & ~RF_INVISIBLE) | savedvisibility; + if (camera != nullptr) camera->renderflags = (camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility; GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); { @@ -1011,6 +1015,23 @@ void GLLineToLinePortal::DrawContents() P_TranslatePortalXY(origin, ViewActorPos.X, ViewActorPos.Y); P_TranslatePortalAngle(origin, ViewAngle); P_TranslatePortalZ(origin, ViewPos.Z); + P_TranslatePortalXY(origin, ViewPath[0].X, ViewPath[0].Y); + P_TranslatePortalXY(origin, ViewPath[1].X, ViewPath[1].Y); + if (!r_showviewer && camera != nullptr && P_PointOnLineSidePrecise(ViewPath[0], glport->lines[0]->mDestination) != P_PointOnLineSidePrecise(ViewPath[1], glport->lines[0]->mDestination)) + { + double distp = (ViewPath[0] - ViewPath[1]).Length(); + if (distp > EQUAL_EPSILON) + { + double dist1 = (ViewPos - ViewPath[0]).Length(); + double dist2 = (ViewPos - ViewPath[1]).Length(); + + if (dist1 + dist2 < distp + 1) + { + camera->renderflags |= RF_MAYBEINVISIBLE; + } + } + } + SaveMapSection(); diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 80f810cb5..8a40ec2e2 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -101,6 +101,7 @@ public: private: void DrawPortalStencil(); + DVector3 savedviewpath[2]; DVector3 savedViewPos; DVector3 savedViewActorPos; DAngle savedAngle; diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 7ed4199a1..75d15543e 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -677,6 +677,11 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) if (thruportal == 1) thingorigin += Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup); if (fabs(thingorigin.X - ViewActorPos.X) < 2 && fabs(thingorigin.Y - ViewActorPos.Y) < 2) return; } + // Thing is invisible if close to the camera. + if (thing->renderflags & RF_MAYBEINVISIBLE) + { + if (fabs(thingpos.X - ViewPos.X) < 32 && fabs(thingpos.Y - ViewPos.Y) < 32) return; + } // Too close to the camera. This doesn't look good if it is a sprite. if (fabs(thingpos.X - ViewPos.X) < 2 && fabs(thingpos.Y - ViewPos.Y) < 2) @@ -693,6 +698,10 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) } } } + if (thing == camera) + { + int a = 0; + } // don't draw first frame of a player missile if (thing->flags&MF_MISSILE) @@ -1051,7 +1060,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s player_t *player=&players[consoleplayer]; - if (particle->trans==0) return; + if (particle->alpha==0) return; lightlevel = gl_ClampLight(sector->GetTexture(sector_t::ceiling) == skyflatnum ? sector->GetCeilingLight() : sector->GetFloorLight()); @@ -1091,7 +1100,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s Colormap.ClearColor(); } - trans=particle->trans/255.0f; + trans=particle->alpha; RenderStyle = STYLE_Translucent; OverrideShader = 0; @@ -1203,6 +1212,14 @@ void gl_RenderActorsInPortal(FGLLinePortal *glport) DVector3 newpos = savedpos; sector_t fakesector; + if (!r_showviewer && th == camera) + { + if (fabs(savedpos.X - ViewActorPos.X) < 2 && fabs(savedpos.Y - ViewActorPos.Y) < 2) + { + continue; + } + } + P_TranslatePortalXY(line, newpos.X, newpos.Y); P_TranslatePortalZ(line, newpos.Z); P_TranslatePortalAngle(line, th->Angles.Yaw); diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 5bf5bf450..f4b2f8103 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -2500,6 +2500,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetInventory) ACTION_RETURN_BOOL(false); } + // Do not run this function on voodoo dolls because the way they transfer the inventory to the player will not work with the code below. + if (mobj->player != nullptr) + { + mobj = mobj->player->mo; + } + AInventory *item = mobj->FindInventory(itemtype); if (item != nullptr) diff --git a/src/p_effect.cpp b/src/p_effect.cpp index 827a457ee..eb872edc1 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -62,7 +62,7 @@ CVAR (Bool, r_particles, true, 0); FRandom pr_railtrail("RailTrail"); -#define FADEFROMTTL(a) (255/(a)) +#define FADEFROMTTL(a) (1.f/(a)) // [RH] particle globals WORD NumParticles; @@ -269,11 +269,10 @@ void P_ThinkParticles () continue; } - BYTE oldtrans; - oldtrans = particle->trans; - particle->trans -= particle->fade; + auto oldtrans = particle->alpha; + particle->alpha -= particle->fadestep; particle->size += particle->sizestep; - if (oldtrans < particle->trans || --particle->ttl <= 0 || (particle->size <= 0)) + if (oldtrans < particle->alpha || --particle->ttl <= 0 || (particle->size <= 0)) { // The particle has expired, so free it memset (particle, 0, sizeof(particle_t)); if (prev) @@ -331,9 +330,9 @@ void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &a particle->Vel = vel; particle->Acc = accel; particle->color = ParticleColor(color); - particle->trans = BYTE(startalpha*255); - if (fadestep < 0) particle->fade = FADEFROMTTL(lifetime); - else particle->fade = int(fadestep * 255); + particle->alpha = float(startalpha); + if (fadestep < 0) particle->fadestep = FADEFROMTTL(lifetime); + else particle->fadestep = float(fadestep); particle->ttl = lifetime; particle->bright = !!(flags & PS_FULLBRIGHT); particle->size = size; @@ -392,9 +391,9 @@ particle_t *JitterParticle (int ttl, double drift) for (i = 3; i; i--) particle->Acc[i] = ((1./16384) * (M_Random () - 128) * drift); - particle->trans = 255; // fully opaque + particle->alpha = 1.f; // fully opaque particle->ttl = ttl; - particle->fade = FADEFROMTTL(ttl); + particle->fadestep = FADEFROMTTL(ttl); } return particle; } @@ -622,8 +621,8 @@ void P_DrawSplash2 (int count, const DVector3 &pos, DAngle angle, int updown, in break; p->ttl = 12; - p->fade = FADEFROMTTL(12); - p->trans = 255; + p->fadestep = FADEFROMTTL(12); + p->alpha = 1.f; p->size = 4; p->color = M_Random() & 0x80 ? color1 : color2; p->Vel.Z = M_Random() * zvel; @@ -763,9 +762,9 @@ void P_DrawRailTrail(AActor *source, TArray &portalhits, int color1, int spiralduration = (duration == 0) ? 35 : duration; - p->trans = 255; + p->alpha = 1.f; p->ttl = duration; - p->fade = FADEFROMTTL(spiralduration); + p->fadestep = FADEFROMTTL(spiralduration); p->size = 3; p->bright = fullbright; diff --git a/src/p_effect.h b/src/p_effect.h index eb417d63c..7f3c50e82 100644 --- a/src/p_effect.h +++ b/src/p_effect.h @@ -59,17 +59,17 @@ struct particle_t DVector3 Pos; DVector3 Vel; DVector3 Acc; - BYTE ttl; - BYTE trans; double size; double sizestep; + subsector_t * subsector; + short ttl; BYTE bright; - BYTE fade; + bool notimefreeze; + float fadestep; + float alpha; int color; WORD tnext; WORD snext; - subsector_t * subsector; - bool notimefreeze; }; extern particle_t *Particles; diff --git a/src/polyrenderer/scene/poly_particle.cpp b/src/polyrenderer/scene/poly_particle.cpp index 3d1142b85..275fd4640 100644 --- a/src/polyrenderer/scene/poly_particle.cpp +++ b/src/polyrenderer/scene/poly_particle.cpp @@ -84,16 +84,17 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const Vec4f &clipP } args.uniforms.subsectorDepth = subsectorDepth; + uint32_t alpha = (uint32_t)clamp(particle->alpha * 255.0f + 0.5f, 0.0f, 255.0f); + if (swrenderer::r_swtruecolor) { - uint32_t alpha = particle->trans; args.uniforms.color = (alpha << 24) | (particle->color & 0xffffff); } else { args.uniforms.color = ((uint32_t)particle->color) >> 24; - args.uniforms.srcalpha = particle->trans; - args.uniforms.destalpha = 255 - particle->trans; + args.uniforms.srcalpha = alpha; + args.uniforms.destalpha = 255 - alpha; } args.objectToClip = &worldToClip; diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index 7a6997746..d5dbbdbfa 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -10154,7 +10154,7 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build) } emitval.Free(build); } - else if (Init->ExprType != EFX_LocalVariable) + else if (!emitval.Fixed) { // take over the register that got allocated while emitting the Init expression. RegNum = emitval.RegNum; diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index 2dbc6562c..c6dd2d5df 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -193,7 +193,7 @@ namespace swrenderer vis->startfrac = 255 & (particle->color >> 24); vis->pic = NULL; vis->bIsVoxel = false; - vis->renderflags = particle->trans; + vis->renderflags = (short)(particle->alpha * 255.0f + 0.5f); vis->FakeFlatStat = fakeside; vis->floorclip = 0; vis->Style.ColormapNum = 0;