233 lines
5.5 KiB
C
Executable file
233 lines
5.5 KiB
C
Executable file
/***
|
|
*
|
|
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
|
|
*
|
|
* See the file LICENSE attached with the sources for usage details.
|
|
*
|
|
****/
|
|
|
|
void View_Init(void)
|
|
{
|
|
#ifdef CSTRIKE
|
|
string wm;
|
|
for ( int i = 0; i < ( CS_WEAPON_COUNT - 1 ); i++ ) {
|
|
wm = sprintf("models/%s", sViewModels[i]);
|
|
precache_model(wm);
|
|
}
|
|
#endif
|
|
|
|
for (int s = seats.length; s-- > numclientseats;) {
|
|
pSeat = &seats[s];
|
|
if( !pSeat->eViewModel ) {
|
|
pSeat->eViewModel = spawn();
|
|
pSeat->eViewModel.classname = "vm";
|
|
pSeat->eViewModel.renderflags = RF_DEPTHHACK;
|
|
|
|
pSeat->eMuzzleflash = spawn();
|
|
pSeat->eMuzzleflash.classname = "mflash";
|
|
pSeat->eMuzzleflash.renderflags = RF_ADDITIVE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void View_CalcViewport(int s, float fWinWidth, float fWinHeight) {
|
|
//FIXME: this is awkward. renderscene internally rounds to pixels.
|
|
//on the other hand, drawpic uses linear filtering and multisample and stuff.
|
|
//this means that there can be a pixel or so difference between scene and 2d.
|
|
//as a general rule, you won't notice unless there's some big drawfills.
|
|
switch (numclientseats) {
|
|
case 3:
|
|
if (!s) {
|
|
case 2:
|
|
video_res = [fWinWidth, fWinHeight * 0.5];
|
|
video_mins = [0, (s & 1) * video_res[1]];
|
|
break;
|
|
}
|
|
s++;
|
|
case 4:
|
|
video_res = [fWinWidth, fWinHeight] * 0.5;
|
|
video_mins = [(s&1) * video_res[0], (s / 2i) * video_res[1]];
|
|
break;
|
|
default:
|
|
video_res = [fWinWidth, fWinHeight];
|
|
video_mins = [0, 0];
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
====================
|
|
View_CalcBob
|
|
====================
|
|
*/
|
|
void View_CalcBob( void )
|
|
{
|
|
float cycle;
|
|
|
|
vector vel;
|
|
|
|
if ( self.flags & FL_ONGROUND == -1 ) {
|
|
return;
|
|
}
|
|
|
|
pSeat->fBobTime += clframetime;
|
|
cycle = pSeat->fBobTime - (int)( pSeat->fBobTime / autocvar_v_bobcycle ) * autocvar_v_bobcycle;
|
|
cycle /= autocvar_v_bobcycle;
|
|
|
|
if ( cycle < autocvar_v_bobup ) {
|
|
cycle = MATH_PI * cycle / autocvar_v_bobup;
|
|
} else {
|
|
cycle = MATH_PI + MATH_PI * ( cycle - autocvar_v_bobup )/( 1.0 - autocvar_v_bobup );
|
|
}
|
|
|
|
vel = pSeat->vPlayerVelocity;
|
|
vel_z = 0;
|
|
|
|
float fBob = sqrt( vel_x * vel_x + vel_y * vel_y ) * autocvar_v_bob;
|
|
fBob = fBob * 0.3 + fBob * 0.7 * sin( cycle );
|
|
pSeat->fBob = bound( -7, fBob, 4 );
|
|
}
|
|
|
|
/*
|
|
====================
|
|
View_DropPunchAngle
|
|
|
|
Quickly lerp to the original viewposition
|
|
====================
|
|
*/
|
|
void View_DropPunchAngle( void ) {
|
|
float lerp;
|
|
lerp = 1.0f - ( clframetime * 4 );
|
|
pSeat->vPunchAngle *= lerp;
|
|
}
|
|
|
|
/*
|
|
====================
|
|
View_AddPunchAngle
|
|
|
|
Gives the angle a bit of an offset/punch/kick
|
|
====================
|
|
*/
|
|
void View_AddPunchAngle( vector add )
|
|
{
|
|
pSeat->vPunchAngle /*+*/= add;
|
|
}
|
|
|
|
/*
|
|
====================
|
|
View_DrawViewModel
|
|
|
|
Really convoluted function that makes the gun,
|
|
muzzleflash, dynamic lights and so on appear
|
|
====================
|
|
*/
|
|
void View_DrawViewModel( void )
|
|
{
|
|
entity eViewModel = pSeat->eViewModel;
|
|
entity eMuzzleflash = pSeat->eMuzzleflash;
|
|
|
|
player pl = (player) self;
|
|
|
|
if ( pl.health <= 0 ) {
|
|
return;
|
|
}
|
|
|
|
// Don't update when paused
|
|
if ( serverkey( "pausestate" ) == "0" ) {
|
|
View_CalcBob();
|
|
View_UpdateWeapon(eViewModel, eMuzzleflash);
|
|
float fBaseTime = eViewModel.frame1time;
|
|
eViewModel.frame1time += clframetime;
|
|
eViewModel.frame2time += clframetime;
|
|
processmodelevents( eViewModel.modelindex, eViewModel.frame, fBaseTime, eViewModel.frame1time, Event_ProcessModel );
|
|
}
|
|
|
|
makevectors(view_angles);
|
|
eViewModel.angles = view_angles;
|
|
eViewModel.origin = pSeat->vPlayerOrigin + pl.view_ofs;
|
|
eViewModel.origin += '0 0 -1' + ( v_forward * ( pSeat->fBob * 0.4 ) )
|
|
+ ( v_forward * autocvar_v_gunofs[0] )
|
|
+ ( v_right * autocvar_v_gunofs[1] )
|
|
+ ( v_up * autocvar_v_gunofs[2] );
|
|
|
|
// Left-handed weapons
|
|
if ( autocvar_v_lefthanded ) {
|
|
v_right *= -1;
|
|
eViewModel.renderflags |= RF_USEAXIS;
|
|
eViewModel.forceshader = SHADER_CULLED;
|
|
} else {
|
|
if ( eViewModel.forceshader ) {
|
|
eViewModel.forceshader = 0;
|
|
eViewModel.renderflags -= RF_USEAXIS;
|
|
}
|
|
}
|
|
|
|
// Give the gun a tilt effect like in old HL/CS versions
|
|
if ( autocvar_v_bobclassic == 1 ) {
|
|
eViewModel.angles_z = -pSeat->fBob;
|
|
}
|
|
|
|
// Only bother when zoomed out
|
|
if ( pl.viewzoom == 1.0f ) {
|
|
// Update muzzleflash position and draw it
|
|
if ( eMuzzleflash.alpha > 0.0f ) {
|
|
makevectors(getproperty(VF_ANGLES));
|
|
eMuzzleflash.origin = gettaginfo( eViewModel, eMuzzleflash.skin );
|
|
dynamiclight_add( pSeat->vPlayerOrigin + (v_forward * 32), 400 * eMuzzleflash.alpha, '1 0.45 0');
|
|
addentity( eMuzzleflash );
|
|
}
|
|
addentity( eViewModel );
|
|
}
|
|
}
|
|
|
|
void View_PostDraw(void)
|
|
{
|
|
entity eMuzzleflash = pSeat->eMuzzleflash;
|
|
|
|
// Take away alpha once it has drawn fully at least once
|
|
if ( eMuzzleflash.alpha > 0.0f ) {
|
|
eMuzzleflash.alpha -= ( clframetime * 16 );
|
|
}
|
|
}
|
|
|
|
void View_Stairsmooth(void)
|
|
{
|
|
vector currentpos = pSeat->vPlayerOrigin;
|
|
vector endpos = currentpos;
|
|
static vector oldpos;
|
|
|
|
/* Have we gone up since last frame? */
|
|
if ( ( pSeat->fPlayerFlags & FL_ONGROUND ) && ( endpos[2] - oldpos[2] > 0 ) ) {
|
|
endpos[2] = oldpos[2] += (frametime * 150);
|
|
|
|
if ( endpos[2] > currentpos[2] ) {
|
|
endpos[2] = currentpos[2];
|
|
}
|
|
if ( currentpos[2] - endpos[2] > 18 ) {
|
|
endpos[2] = currentpos[2] - 18;
|
|
}
|
|
}
|
|
|
|
// Teleport hack
|
|
if ( fabs( currentpos[2] - oldpos[2] ) > 64 ) {
|
|
endpos[2] = currentpos[2];
|
|
}
|
|
|
|
//setproperty(VF_ORIGIN, endpos);
|
|
pSeat->vPlayerOrigin = endpos;
|
|
oldpos = endpos;
|
|
}
|
|
|
|
/*
|
|
====================
|
|
View_PlayAnimation
|
|
|
|
Resets the timeline and plays a new sequence
|
|
onto the view model
|
|
====================
|
|
*/
|
|
void View_PlayAnimation( int iSequence )
|
|
{
|
|
pSeat->eViewModel.frame = (float)iSequence;
|
|
pSeat->eViewModel.frame1time = 0.0f;
|
|
}
|