| Shell Effects | |
| Additional features | |
| Adding weapons to the shell. | |
|
The shell only covers the player model, because weapons are passed to the renderer as separate entities. In order for the shell to include additional models we need to work on the function CL_AddPacketEntities in client\cl_ents.c | |
// color shells generate a seperate entity for the main model
if (effects & EF_COLOR_SHELL)
{
// PMM - at this point, all of the shells have been handled
// if we're in the rogue pack, set up the custom mixing, otherwise just
// keep going
// if(Developer_searchpath(2) == 2)
// {
// all of the solo colors are fine. we need to catch any of the combinations that look bad
// (double & half) and turn them into the appropriate color, and make double/quad something special
if (renderfx & RF_SHELL_HALF_DAM)
{
if(Developer_searchpath(2) == 2)
{
// ditch the half damage shell if any of red, blue, or double are on
if (renderfx & (RF_SHELL_RED|RF_SHELL_BLUE|RF_SHELL_DOUBLE))
renderfx &= ~RF_SHELL_HALF_DAM;
}
}
if (renderfx & RF_SHELL_DOUBLE)
{
if(Developer_searchpath(2) == 2)
{
// lose the yellow shell if we have a red, blue, or green shell
if (renderfx & (RF_SHELL_RED|RF_SHELL_BLUE|RF_SHELL_GREEN))
renderfx &= ~RF_SHELL_DOUBLE;
// if we have a red shell, turn it to purple by adding blue
if (renderfx & RF_SHELL_RED)
renderfx |= RF_SHELL_BLUE;
// if we have a blue shell (and not a red shell), turn it to cyan by adding green
else if (renderfx & RF_SHELL_BLUE)
// go to green if it's on already, otherwise do cyan (flash green)
if (renderfx & RF_SHELL_GREEN)
renderfx &= ~RF_SHELL_BLUE;
else
renderfx |= RF_SHELL_GREEN;
}
}
// }
// pmm
ent.flags = renderfx | RF_TRANSLUCENT;
ent.alpha = 0.30;
V_AddEntity (&ent);
}
ent.skin = NULL; // never use a custom skin on others
ent.skinnum = 0;
ent.flags = 0;
ent.alpha = 0;
| |
| Add in the section near the bottom after the line which says // c14 add linked models under shell | |
// color shells generate a seperate entity for the main model
if (effects & EF_COLOR_SHELL)
{
// PMM - at this point, all of the shells have been handled
// if we're in the rogue pack, set up the custom mixing, otherwise just
// keep going
// if(Developer_searchpath(2) == 2)
// {
// all of the solo colors are fine. we need to catch any of the combinations that look bad
// (double & half) and turn them into the appropriate color, and make double/quad something special
if (renderfx & RF_SHELL_HALF_DAM)
{
if(Developer_searchpath(2) == 2)
{
// ditch the half damage shell if any of red, blue, or double are on
if (renderfx & (RF_SHELL_RED|RF_SHELL_BLUE|RF_SHELL_DOUBLE))
renderfx &= ~RF_SHELL_HALF_DAM;
}
}
if (renderfx & RF_SHELL_DOUBLE)
{
if(Developer_searchpath(2) == 2)
{
// lose the yellow shell if we have a red, blue, or green shell
if (renderfx & (RF_SHELL_RED|RF_SHELL_BLUE|RF_SHELL_GREEN))
renderfx &= ~RF_SHELL_DOUBLE;
// if we have a red shell, turn it to purple by adding blue
if (renderfx & RF_SHELL_RED)
renderfx |= RF_SHELL_BLUE;
// if we have a blue shell (and not a red shell), turn it to cyan by adding green
else if (renderfx & RF_SHELL_BLUE)
// go to green if it's on already, otherwise do cyan (flash green)
if (renderfx & RF_SHELL_GREEN)
renderfx &= ~RF_SHELL_BLUE;
else
renderfx |= RF_SHELL_GREEN;
}
}
// }
// pmm
ent.flags = renderfx | RF_TRANSLUCENT;
ent.alpha = 0.30;
V_AddEntity (&ent);
// c14 add linked models under shell
// duplicate for linked models
if (s1->modelindex2)
{
if (s1->modelindex2 == 255)
{ // custom weapon
ci = &cl.clientinfo[s1->skinnum & 0xff];
i = (s1->skinnum >> 8); // 0 is default weapon model
if (!cl_vwep->value || i > MAX_CLIENTWEAPONMODELS - 1)
i = 0;
ent.model = ci->weaponmodel[i];
if (!ent.model) {
if (i != 0)
ent.model = ci->weaponmodel[0];
if (!ent.model)
ent.model = cl.baseclientinfo.weaponmodel[0];
}
}
else
ent.model = cl.model_draw[s1->modelindex2];
V_AddEntity (&ent);
}
if (s1->modelindex3)
{
ent.model = cl.model_draw[s1->modelindex3];
V_AddEntity (&ent);
}
if (s1->modelindex4)
{
ent.model = cl.model_draw[s1->modelindex4];
V_AddEntity (&ent);
}
}
ent.skin = NULL; // never use a custom skin on others
ent.skinnum = 0;
ent.flags = 0;
ent.alpha = 0;
| |
| Adding a glow to the shell. | |
|
The shell does not cast any light, even though we kind of expect it to be a "glowing" shell. Actually we could in theory have black
shells, but implementing them would be a huge task. We'll add a dynamic light with the shell and this will illuminate the walls around the model, and also the model itself The changes also need to be made in CL_AddPacketEntities in client\cl_ents.c<\tt> | |
if (s1->number == cl.playernum+1)
{
ent.flags |= RF_VIEWERMODEL; // only draw from mirrors
// FIXME: still pass to refresh
if (effects & EF_FLAG1)
V_AddLight (ent.origin, 225, 1.0, 0.1, 0.1);
else if (effects & EF_FLAG2)
V_AddLight (ent.origin, 225, 0.1, 0.1, 1.0);
else if (effects & EF_TAGTRAIL) //PGM
V_AddLight (ent.origin, 225, 1.0, 1.0, 0.0); //PGM
else if (effects & EF_TRACKERTRAIL) //PGM
V_AddLight (ent.origin, 225, -1.0, -1.0, -1.0); //PGM
continue;
}
// if set to invisible, skip
if (!s1->modelindex)
continue;
| |
| Add in the section near the bottom after the line which says // c14 illuminating shells | |
if (s1->number == cl.playernum+1)
{
ent.flags |= RF_VIEWERMODEL; // only draw from mirrors
// FIXME: still pass to refresh
if (effects & EF_FLAG1)
V_AddLight (ent.origin, 225, 1.0, 0.1, 0.1);
else if (effects & EF_FLAG2)
V_AddLight (ent.origin, 225, 0.1, 0.1, 1.0);
else if (effects & EF_TAGTRAIL) //PGM
V_AddLight (ent.origin, 225, 1.0, 1.0, 0.0); //PGM
else if (effects & EF_TRACKERTRAIL) //PGM
V_AddLight (ent.origin, 225, -1.0, -1.0, -1.0); //PGM
continue;
}
// c14 illuminating shells
if (renderfx & RF_SHELL_RED)
V_AddLight(ent.origin, 100, 1.0, 0.0, 0.0);
if (renderfx & RF_SHELL_BLUE)
V_AddLight(ent.origin, 100, 0.0, 0.0, 1.0);
if (renderfx & RF_SHELL_GREEN)
V_AddLight(ent.origin, 100, 0.0, 1.0, 0.0);
// if set to invisible, skip
if (!s1->modelindex)
continue;
| |
|
You might want to extend this code to deal with RF_SHELL_DOUBLE and RF_SHELL_HALF_DAM. The function V_AddLight takes 5 parameters.
| |
| Adding a glow to the view weapon. | |
|
When you have a colored shell, then typically there is a colored blend over the entire view, but this is controlled by the game
not by the engine. We'll add the same shell effect that other players see, to your own view weapon. The changes need to be made in CL_AddViewWeapon in client\cl_ents.c<\tt> | |
/*
==============
CL_AddViewWeapon
==============
*/
void CL_AddViewWeapon (player_state_t *ps, player_state_t *ops)
{
entity_t gun; // view model
int i;
// allow the gun to be completely removed
if (!cl_gun->value)
return;
// don't draw gun if in wide angle view
if (ps->fov > 90)
return;
memset (&gun, 0, sizeof(gun));
if (gun_model)
gun.model = gun_model; // development tool
else
gun.model = cl.model_draw[ps->gunindex];
if (!gun.model)
return;
// set up gun position
for (i=0 ; i<3 ; i++)
{
gun.origin[i] = cl.refdef.vieworg[i] + ops->gunoffset[i]
+ cl.lerpfrac * (ps->gunoffset[i] - ops->gunoffset[i]);
gun.angles[i] = cl.refdef.viewangles[i] + LerpAngle (ops->gunangles[i],
ps->gunangles[i], cl.lerpfrac);
}
if (gun_frame)
{
gun.frame = gun_frame; // development tool
gun.oldframe = gun_frame; // development tool
}
else
{
gun.frame = ps->gunframe;
if (gun.frame == 0)
gun.oldframe = 0; // just changed weapons, don't lerp from old
else
gun.oldframe = ops->gunframe;
}
gun.flags = RF_MINLIGHT | RF_DEPTHHACK | RF_WEAPONMODEL;
gun.backlerp = 1.0 - cl.lerpfrac;
VectorCopy (gun.origin, gun.oldorigin); // don't lerp at all
V_AddEntity (&gun);
}
| |
| Add two lines near the top, and the section near the bottom after the line which says // c14 add shell to view model | |
/*
==============
CL_AddViewWeapon
==============
*/
void CL_AddViewWeapon (player_state_t *ps, player_state_t *ops)
{
entity_t gun; // view model
int i;
int pnum; // c14 add shell to view model
entity_state_t *s1; // c14 add shell to view model
// allow the gun to be completely removed
if (!cl_gun->value)
return;
// don't draw gun if in wide angle view
if (ps->fov > 90)
return;
memset (&gun, 0, sizeof(gun));
if (gun_model)
gun.model = gun_model; // development tool
else
gun.model = cl.model_draw[ps->gunindex];
if (!gun.model)
return;
// set up gun position
for (i=0 ; i<3 ; i++)
{
gun.origin[i] = cl.refdef.vieworg[i] + ops->gunoffset[i]
+ cl.lerpfrac * (ps->gunoffset[i] - ops->gunoffset[i]);
gun.angles[i] = cl.refdef.viewangles[i] + LerpAngle (ops->gunangles[i],
ps->gunangles[i], cl.lerpfrac);
}
if (gun_frame)
{
gun.frame = gun_frame; // development tool
gun.oldframe = gun_frame; // development tool
}
else
{
gun.frame = ps->gunframe;
if (gun.frame == 0)
gun.oldframe = 0; // just changed weapons, don't lerp from old
else
gun.oldframe = ops->gunframe;
}
gun.flags = RF_MINLIGHT | RF_DEPTHHACK | RF_WEAPONMODEL;
gun.backlerp = 1.0 - cl.lerpfrac;
VectorCopy (gun.origin, gun.oldorigin); // don't lerp at all
V_AddEntity (&gun);
// c14 add shell to view model
for (pnum = 0 ; pnum<cl.frame.num_entities ; pnum++)
{
s1 = &cl_parse_entities[(cl.frame.parse_entities+pnum)&(MAX_PARSE_ENTITIES-1)];
if (s1->number != cl.playernum + 1)
continue;
if (s1->effects & (EF_COLOR_SHELL|EF_QUAD|EF_PENT|EF_DOUBLE|EF_HALF_DAMAGE))
{
gun.flags |= (RF_TRANSLUCENT|s1->renderfx);
if (s1->effects & EF_PENT)
gun.flags |= RF_SHELL_RED;
if (s1->effects & EF_QUAD)
gun.flags |= RF_SHELL_BLUE;
if (s1->effects & EF_DOUBLE)
gun.flags |= RF_SHELL_DOUBLE;
if (s1->effects & EF_HALF_DAMAGE)
gun.flags |= RF_SHELL_HALF_DAM;
gun.alpha = 0.1;
V_AddEntity(&gun);
}
}
}
|