diff --git a/Plugins/Renderer/exportfuncs.cpp b/Plugins/Renderer/exportfuncs.cpp index 8a07c8aa..316f1d17 100644 --- a/Plugins/Renderer/exportfuncs.cpp +++ b/Plugins/Renderer/exportfuncs.cpp @@ -1884,8 +1884,15 @@ int HUD_GetStudioModelInterface(int version, struct r_studio_interface_s **ppint int HUD_AddEntity(int type, cl_entity_t *ent, const char *model) { + CEntityComponentContainer* pEntityComponentContainer = nullptr; + int r = gExportfuncs.HUD_AddEntity(type, ent, model); + if (r && ent->model) + { + pEntityComponentContainer = R_GetEntityComponentContainer(ent, true); + } + if (r && ent->curstate.movetype == MOVETYPE_FOLLOW && ent->curstate.aiment > 0 && @@ -1895,18 +1902,9 @@ int HUD_AddEntity(int type, cl_entity_t *ent, const char *model) { auto aiment = gEngfuncs.GetEntityByIndex(ent->curstate.aiment); - auto pEntityComponentContainerAimEnt = R_GetEntityComponentContainer(aiment, true); - - if (pEntityComponentContainerAimEnt) - { - pEntityComponentContainerAimEnt->FollowEnts.emplace_back(ent); - } - - auto pEntityComponentContainerFollowEnt = R_GetEntityComponentContainer(ent, true); - - if (pEntityComponentContainerFollowEnt) + if (aiment && pEntityComponentContainer) { - pEntityComponentContainerFollowEnt->AimEntity = aiment; + pEntityComponentContainer->AimEntity = aiment; } } diff --git a/Plugins/Renderer/gl_entity.cpp b/Plugins/Renderer/gl_entity.cpp index 1fad9ddc..a7870786 100644 --- a/Plugins/Renderer/gl_entity.cpp +++ b/Plugins/Renderer/gl_entity.cpp @@ -16,7 +16,7 @@ void R_InitEntityComponents(void) for (int i = 0; i < MAX_ENTITY_COMPONENTS; i++) { gEntityComponentPool[i].pNext = &gEntityComponentPool[i + 1]; - gEntityComponentPool[i].FollowEnts.clear(); + //gEntityComponentPool[i].FollowEnts.clear(); gEntityComponentPool[i].Decals.clear(); gEntityComponentPool[i].WaterVBOs.clear(); gEntityComponentPool[i].ReflectCaches.clear(); @@ -58,7 +58,7 @@ void R_EntityComponents_PreFrame(void) auto p = gpEntityComponentActive; while (p) { - p->FollowEnts.clear(); + //p->FollowEnts.clear(); p->Decals.clear(); p->WaterVBOs.clear(); p->ReflectCaches.clear(); diff --git a/Plugins/Renderer/gl_entity.h b/Plugins/Renderer/gl_entity.h index c8b5cadc..2f192386 100644 --- a/Plugins/Renderer/gl_entity.h +++ b/Plugins/Renderer/gl_entity.h @@ -35,7 +35,7 @@ class CEntityComponentContainer { public: CEntityComponentContainer* pNext{}; - std::vector FollowEnts; + //std::vector FollowEnts; std::vector Decals; std::vector WaterVBOs; std::vector ReflectCaches; diff --git a/Plugins/Renderer/gl_rmain.cpp b/Plugins/Renderer/gl_rmain.cpp index 6531a8fb..e5ef283b 100644 --- a/Plugins/Renderer/gl_rmain.cpp +++ b/Plugins/Renderer/gl_rmain.cpp @@ -1309,7 +1309,23 @@ void R_DrawCurrentEntity(bool bTransparent) { auto pEntityComponentContainer = R_GetEntityComponentContainer((*currententity), false); - if (pEntityComponentContainer && pEntityComponentContainer->AimEntity) + if (!pEntityComponentContainer || !pEntityComponentContainer->AimEntity) + { + //No aiment found? + return; + } + + auto aiment = pEntityComponentContainer->AimEntity; + + auto pEntityComponentContainerAimEnt = R_GetEntityComponentContainer(aiment, false); + + //The aiment is invisible ? hide me. + if (!pEntityComponentContainerAimEnt) + { + return; + } + + if (aiment->model && aiment->model->type == mod_studio) { auto saved_currententity = (*currententity); @@ -1325,15 +1341,15 @@ void R_DrawCurrentEntity(bool bTransparent) } (*currententity) = saved_currententity; + } - if ((*currententity)->player) - { - (*gpStudioInterface)->StudioDrawPlayer(STUDIO_RENDER | STUDIO_EVENTS, R_GetPlayerState((*currententity)->index)); - } - else - { - (*gpStudioInterface)->StudioDrawModel(STUDIO_RENDER | STUDIO_EVENTS); - } + if ((*currententity)->player) + { + (*gpStudioInterface)->StudioDrawPlayer(STUDIO_RENDER | STUDIO_EVENTS, R_GetPlayerState((*currententity)->index)); + } + else + { + (*gpStudioInterface)->StudioDrawModel(STUDIO_RENDER | STUDIO_EVENTS); } return; } @@ -4005,65 +4021,142 @@ int __cdecl SDL_GL_SetAttribute(int attr, int value) return gPrivateFuncs.SDL_GL_SetAttribute(attr, value); } +void CL_EmitPlayerFlashlight(int entindex) +{ + cl_entity_t* ent = gEngfuncs.GetEntityByIndex(entindex); + + if (!ent->player) + return; + + dlight_t* dl = nullptr; + + // JAY: Flashlight effect. Currently just a light that floats in from of + // the player a few feet. Using 3 lights is better looking, but SLOW. + // A conical light projection might look better and be more efficient. + + // BRJ: Modified the flashlight to use a true spotlight for model illumination + // and uses Jay's old method of making a spherical light that only illuminates + // the lightmaps at the intersection point. + + if (ent->curstate.effects & (EF_BRIGHTLIGHT | EF_DIMLIGHT) && r_worldmodel) + { + dl = gEngfuncs.pEfxAPI->CL_AllocDlight(entindex); + + if (ent->curstate.effects & EF_BRIGHTLIGHT) + { + dl->color.r = dl->color.g = dl->color.b = 250; + dl->radius = 400; + VectorCopy(ent->origin, dl->origin); + dl->origin[2] += 16; + } + else + { + vec3_t end; + float falloff; + vec3_t vecForward; + + AngleVectors(r_playerViewportAngles, vecForward, NULL, NULL); + + VectorCopy(ent->origin, dl->origin); + //VectorAdd(ent->origin, cl_viewheight, dl->origin); + VectorMA(dl->origin, r_flashlight_distance->GetValue(), vecForward, end); + + // Trace a line outward, don't use hitboxes (too slow) + pmove->usehull = 2; + auto trace = gEngfuncs.PM_TraceLine(dl->origin, end, PM_STUDIO_BOX, 2, -1); + + if (trace->ent > 0 && pmove->physents[trace->ent].studiomodel) + { + VectorCopy(pmove->physents[trace->ent].origin, dl->origin); + } + else + { + VectorCopy(trace->endpos, dl->origin); + } + + falloff = trace->fraction * r_flashlight_distance->GetValue(); + + if (falloff < 500) + falloff = 1.0; + else + falloff = 500.0 / falloff; + + falloff *= falloff; + + dl->radius = 80; + dl->color.r = dl->color.g = dl->color.b = 255 * falloff; + } + + // Make it live for a bit + dl->die = (*cl_time) + 0.2f; + } +} + void R_SetupFlashlights() { int max_dlight = EngineGetMaxDLights(); dlight_t* dl = cl_dlights; float curtime = (*cl_time); -#if 0 - for (int i = 0; i < max_dlight; i++, dl++) - { - if (dl->die < curtime || !dl->radius) - continue; - if (dl->key == 4) { - memset(dl, 0, sizeof(dlight_t)); - } + if (g_iEngineType == ENGINE_SVENGINE) + { + //SvEngine done a good job here we don't need to setup our own flashlights. } - - for (int i = 0; i < MAX_CLIENTS; ++i) + else { - auto state = R_GetPlayerState(i); + for (int i = 0; i < max_dlight; i++, dl++) + { + if (dl->die < curtime || !dl->radius) + continue; - if (state->messagenum != (*cl_parsecount)) - continue; + if (dl->key == 4 || dl->key == 1) { + memset(dl, 0, sizeof(dlight_t)); + } + } - if (!state->modelindex || (state->effects & EF_NODRAW)) - continue; + for (int i = 0; i < MAX_CLIENTS; ++i) + { + auto state = R_GetPlayerState(i); - auto entindex = state->number; - auto ent = gEngfuncs.GetEntityByIndex(entindex); + if (state->messagenum != (*cl_parsecount)) + continue; - if(!ent) - continue; + if (!state->modelindex || (state->effects & EF_NODRAW)) + continue; - if (ent == gEngfuncs.GetLocalPlayer()) - continue; + auto entindex = state->number; + auto ent = gEngfuncs.GetEntityByIndex(entindex); - if (ent->curstate.effects & EF_BRIGHTLIGHT) - { - dl = gEngfuncs.pEfxAPI->CL_AllocDlight(DLIGHT_KEY_PLAYER_BRIGHTLIGHT + entindex); - if (dl) + if (!ent) + continue; + + if (ent->curstate.effects & EF_BRIGHTLIGHT) { - VectorCopy(ent->origin, dl->origin); - dl->origin[2] += 16; - dl->color.r = dl->color.g = dl->color.b = 250; - dl->radius = gEngfuncs.pfnRandomFloat(400, 431); - dl->die = (*cl_time) + 0.001f; + dl = gEngfuncs.pEfxAPI->CL_AllocDlight(DLIGHT_KEY_PLAYER_BRIGHTLIGHT + entindex); + if (dl) + { + VectorCopy(ent->origin, dl->origin); + dl->origin[2] += 16; + dl->color.r = dl->color.g = dl->color.b = 250; + dl->radius = gEngfuncs.pfnRandomFloat(400, 431); + dl->die = (*cl_time) + 0.001f; + } } - } - if (ent->curstate.effects & EF_DIMLIGHT) - { - dl = gEngfuncs.pEfxAPI->CL_AllocDlight(DLIGHT_KEY_PLAYER_FLASHLIGHT + entindex); - if (dl) + if (ent->curstate.effects & EF_DIMLIGHT) { - VectorCopy(ent->origin, dl->origin); - dl->color.r = dl->color.g = dl->color.b = 100; - dl->radius = gEngfuncs.pfnRandomFloat(200, 231); - dl->die = (*cl_time) + 0.001f; + CL_EmitPlayerFlashlight(entindex); + + dl = gEngfuncs.pEfxAPI->CL_AllocDlight(DLIGHT_KEY_PLAYER_FLASHLIGHT + entindex); + if (dl) + { + VectorCopy(ent->origin, dl->origin); + dl->color.r = dl->color.g = dl->color.b = 100; + dl->radius = gEngfuncs.pfnRandomFloat(200, 231); + dl->die = (*cl_time) + 0.001f; + } } } } -#endif + } \ No newline at end of file