diff options
Diffstat (limited to 'game/client/portal/c_weapon_portalgun.cpp')
| -rw-r--r-- | game/client/portal/c_weapon_portalgun.cpp | 1112 |
1 files changed, 1112 insertions, 0 deletions
diff --git a/game/client/portal/c_weapon_portalgun.cpp b/game/client/portal/c_weapon_portalgun.cpp new file mode 100644 index 0000000..9695158 --- /dev/null +++ b/game/client/portal/c_weapon_portalgun.cpp @@ -0,0 +1,1112 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" + +#include "c_portal_player.h" +#include "c_te_effect_dispatch.h" +#include "iviewrender_beams.h" +#include "model_types.h" +#include "fx_interpvalue.h" +#include "clienteffectprecachesystem.h" +#include "bone_setup.h" +#include "c_rumble.h" +#include "rumble_shared.h" + +#include "weapon_portalgun_shared.h" + + +#define SPRITE_SCALE 128.0f + +ConVar cl_portalgun_effects_min_alpha ("cl_portalgun_effects_min_alpha", "96", FCVAR_CLIENTDLL ); +ConVar cl_portalgun_effects_max_alpha ("cl_portalgun_effects_max_alpha", "128", FCVAR_CLIENTDLL ); + +ConVar cl_portalgun_effects_min_size ("cl_portalgun_effects_min_size", "3.0", FCVAR_CLIENTDLL ); +ConVar cl_portalgun_beam_size ("cl_portalgun_beam_size", "0.04", FCVAR_CLIENTDLL ); + +// HACK HACK! Used to make the gun visually change when going through a cleanser! +//ConVar cl_portalgun_effects_max_size ("cl_portalgun_effects_max_size", "2.5", FCVAR_REPLICATED ); + + +//Precahce the effects +CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectPortalgun ) +CLIENTEFFECT_MATERIAL( PORTALGUN_BEAM_SPRITE ) +CLIENTEFFECT_MATERIAL( PORTALGUN_BEAM_SPRITE_NOZ ) +CLIENTEFFECT_MATERIAL( PORTALGUN_GLOW_SPRITE ) +CLIENTEFFECT_MATERIAL( PORTALGUN_ENDCAP_SPRITE ) +CLIENTEFFECT_MATERIAL( PORTALGUN_GRAV_ACTIVE_GLOW ) +CLIENTEFFECT_MATERIAL( PORTALGUN_PORTAL1_FIRED_LAST_GLOW ) +CLIENTEFFECT_MATERIAL( PORTALGUN_PORTAL2_FIRED_LAST_GLOW ) +CLIENTEFFECT_MATERIAL( PORTALGUN_PORTAL_MUZZLE_GLOW_SPRITE ) +CLIENTEFFECT_MATERIAL( PORTALGUN_PORTAL_TUBE_BEAM_SPRITE ) +CLIENTEFFECT_REGISTER_END() + + +CPortalgunEffectBeam::CPortalgunEffectBeam( void ) + : m_pBeam( NULL ), + m_fBrightness( 255.0f ) +{} + +CPortalgunEffectBeam::~CPortalgunEffectBeam( void ) +{ + Release(); +} + +void CPortalgunEffectBeam::Release( void ) +{ + if ( m_pBeam != NULL ) + { + m_pBeam->flags = 0; + m_pBeam->die = gpGlobals->curtime - 1; + + m_pBeam = NULL; + } +} + +void CPortalgunEffectBeam::Init( int startAttachment, int endAttachment, CBaseEntity *pEntity, bool firstPerson ) +{ + if ( m_pBeam != NULL ) + return; + + BeamInfo_t beamInfo; + + beamInfo.m_pStartEnt = pEntity; + beamInfo.m_nStartAttachment = startAttachment; + beamInfo.m_pEndEnt = pEntity; + beamInfo.m_nEndAttachment = endAttachment; + beamInfo.m_nType = TE_BEAMPOINTS; + beamInfo.m_vecStart = vec3_origin; + beamInfo.m_vecEnd = vec3_origin; + + beamInfo.m_pszModelName = ( firstPerson ) ? PORTALGUN_BEAM_SPRITE_NOZ : PORTALGUN_BEAM_SPRITE; + + beamInfo.m_flHaloScale = 0.0f; + beamInfo.m_flLife = 0.0f; + + if ( firstPerson ) + { + beamInfo.m_flWidth = 0.0f; + beamInfo.m_flEndWidth = 2.0f; + } + else + { + beamInfo.m_flWidth = 0.5f; + beamInfo.m_flEndWidth = 2.0f; + } + + beamInfo.m_flFadeLength = 0.0f; + beamInfo.m_flAmplitude = 16; + beamInfo.m_flBrightness = 128.0; + beamInfo.m_flSpeed = 150.0f; + beamInfo.m_nStartFrame = 0.0; + beamInfo.m_flFrameRate = 30.0; + beamInfo.m_flRed = 255.0; + beamInfo.m_flGreen = 255.0; + beamInfo.m_flBlue = 255.0; + beamInfo.m_nSegments = 8; + beamInfo.m_bRenderable = true; + beamInfo.m_nFlags = FBEAM_FOREVER; + + m_pBeam = beams->CreateBeamEntPoint( beamInfo ); + + if ( m_pBeam ) + { + m_pBeam->m_bDrawInMainRender = false; + m_pBeam->m_bDrawInPortalRender = false; + } +} + +void CPortalgunEffectBeam::SetVisibleViewModel( bool visible /*= true*/ ) +{ + if ( m_pBeam == NULL ) + return; + + m_pBeam->m_bDrawInMainRender = visible; +} + +int CPortalgunEffectBeam::IsVisibleViewModel( void ) const +{ + if ( m_pBeam == NULL ) + return false; + + return m_pBeam->m_bDrawInMainRender; +} + +void CPortalgunEffectBeam::SetVisible3rdPerson( bool visible /*= true*/ ) +{ + if ( m_pBeam == NULL ) + return; + + m_pBeam->m_bDrawInPortalRender = visible; +} + +int CPortalgunEffectBeam::SetVisible3rdPerson( void ) const +{ + if ( m_pBeam == NULL ) + return false; + + return m_pBeam->m_bDrawInPortalRender; +} + +void CPortalgunEffectBeam::SetBrightness( float fBrightness ) +{ + m_fBrightness = clamp( fBrightness, 0.0f, 255.0f ); +} + +void CPortalgunEffectBeam::DrawBeam( void ) +{ + if ( m_pBeam ) + m_pBeam->DrawModel( 0 ); +} + + +IMPLEMENT_NETWORKCLASS_ALIASED( WeaponPortalgun, DT_WeaponPortalgun ) + +BEGIN_NETWORK_TABLE( C_WeaponPortalgun, DT_WeaponPortalgun ) + RecvPropBool( RECVINFO( m_bCanFirePortal1 ) ), + RecvPropBool( RECVINFO( m_bCanFirePortal2 ) ), + RecvPropInt( RECVINFO( m_iLastFiredPortal ) ), + RecvPropBool( RECVINFO( m_bOpenProngs ) ), + RecvPropFloat( RECVINFO( m_fCanPlacePortal1OnThisSurface ) ), + RecvPropFloat( RECVINFO( m_fCanPlacePortal2OnThisSurface ) ), + RecvPropFloat( RECVINFO( m_fEffectsMaxSize1 ) ), // HACK HACK! Used to make the gun visually change when going through a cleanser! + RecvPropFloat( RECVINFO( m_fEffectsMaxSize2 ) ), + RecvPropInt( RECVINFO( m_EffectState ) ), +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA( C_WeaponPortalgun ) + DEFINE_PRED_FIELD( m_bCanFirePortal1, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_bCanFirePortal2, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_iLastFiredPortal, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_bOpenProngs, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_fCanPlacePortal1OnThisSurface, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_fCanPlacePortal2OnThisSurface, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_EffectState, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), +END_PREDICTION_DATA() + +LINK_ENTITY_TO_CLASS( weapon_portalgun, C_WeaponPortalgun ); +PRECACHE_WEAPON_REGISTER(weapon_portalgun); + + +void C_WeaponPortalgun::Spawn( void ) +{ + Precache(); + + BaseClass::Spawn(); + + //SetThink( &C_BaseEntity::Think ); + SetNextThink( gpGlobals->curtime + 0.1 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_WeaponPortalgun::StartEffects( void ) +{ + int i; + + CBaseEntity *pModelView = ( ( GetOwner() ) ? ( ToBasePlayer( GetOwner() )->GetViewModel() ) : ( 0 ) ); + CBaseEntity *pModelWorld = this; + + if ( !pModelView ) + { + pModelView = pModelWorld; + } + + // ------------------------------------------ + // Lights + // ------------------------------------------ + + if ( m_Parameters[PORTALGUN_GRAVLIGHT].GetMaterial() == NULL ) + { + m_Parameters[PORTALGUN_GRAVLIGHT].GetScale().SetAbsolute( 0.018f * SPRITE_SCALE ); + m_Parameters[PORTALGUN_GRAVLIGHT].GetAlpha().SetAbsolute( 128.0f ); + m_Parameters[PORTALGUN_GRAVLIGHT].SetAttachment( pModelView->LookupAttachment( "Body_light" ) ); + m_Parameters[PORTALGUN_GRAVLIGHT].SetVisible( false ); + + if ( m_Parameters[PORTALGUN_GRAVLIGHT].SetMaterial( PORTALGUN_GRAV_ACTIVE_GLOW ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + if ( m_Parameters[PORTALGUN_GRAVLIGHT_WORLD].GetMaterial() == NULL ) + { + m_Parameters[PORTALGUN_GRAVLIGHT_WORLD].GetScale().SetAbsolute( 0.03f * SPRITE_SCALE ); + m_Parameters[PORTALGUN_GRAVLIGHT_WORLD].GetAlpha().SetAbsolute( 128.0f ); + m_Parameters[PORTALGUN_GRAVLIGHT_WORLD].SetAttachment( pModelWorld->LookupAttachment( "Body_light" ) ); + m_Parameters[PORTALGUN_GRAVLIGHT_WORLD].SetVisible( false ); + + if ( m_Parameters[PORTALGUN_GRAVLIGHT_WORLD].SetMaterial( PORTALGUN_GRAV_ACTIVE_GLOW ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + if ( m_Parameters[PORTALGUN_PORTAL1LIGHT].GetMaterial() == NULL ) + { + m_Parameters[PORTALGUN_PORTAL1LIGHT].GetScale().SetAbsolute( 0.018f * SPRITE_SCALE ); + m_Parameters[PORTALGUN_PORTAL1LIGHT].GetAlpha().SetAbsolute( 128.0f ); + m_Parameters[PORTALGUN_PORTAL1LIGHT].SetAttachment( pModelView->LookupAttachment( "Body_light" ) ); + m_Parameters[PORTALGUN_PORTAL1LIGHT].SetVisible( false ); + + if ( m_Parameters[PORTALGUN_PORTAL1LIGHT].SetMaterial( PORTALGUN_PORTAL1_FIRED_LAST_GLOW ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + if ( m_Parameters[PORTALGUN_PORTAL1LIGHT_WORLD].GetMaterial() == NULL ) + { + m_Parameters[PORTALGUN_PORTAL1LIGHT_WORLD].GetScale().SetAbsolute( 0.03f * SPRITE_SCALE ); + m_Parameters[PORTALGUN_PORTAL1LIGHT_WORLD].GetAlpha().SetAbsolute( 128.0f ); + m_Parameters[PORTALGUN_PORTAL1LIGHT_WORLD].SetAttachment( pModelWorld->LookupAttachment( "Body_light" ) ); + m_Parameters[PORTALGUN_PORTAL1LIGHT_WORLD].SetVisible( false ); + + if ( m_Parameters[PORTALGUN_PORTAL1LIGHT_WORLD].SetMaterial( PORTALGUN_PORTAL1_FIRED_LAST_GLOW ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + if ( m_Parameters[PORTALGUN_PORTAL2LIGHT].GetMaterial() == NULL ) + { + m_Parameters[PORTALGUN_PORTAL2LIGHT].GetScale().SetAbsolute( 0.018f * SPRITE_SCALE ); + m_Parameters[PORTALGUN_PORTAL2LIGHT].GetAlpha().SetAbsolute( 128.0f ); + m_Parameters[PORTALGUN_PORTAL2LIGHT].SetAttachment( pModelView->LookupAttachment( "Body_light" ) ); + m_Parameters[PORTALGUN_PORTAL2LIGHT].SetVisible( false ); + + if ( m_Parameters[PORTALGUN_PORTAL2LIGHT].SetMaterial( PORTALGUN_PORTAL2_FIRED_LAST_GLOW ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + if ( m_Parameters[PORTALGUN_PORTAL2LIGHT_WORLD].GetMaterial() == NULL ) + { + m_Parameters[PORTALGUN_PORTAL2LIGHT_WORLD].GetScale().SetAbsolute( 0.03f * SPRITE_SCALE ); + m_Parameters[PORTALGUN_PORTAL2LIGHT_WORLD].GetAlpha().SetAbsolute( 128.0f ); + m_Parameters[PORTALGUN_PORTAL2LIGHT_WORLD].SetAttachment( pModelWorld->LookupAttachment( "Body_light" ) ); + m_Parameters[PORTALGUN_PORTAL2LIGHT_WORLD].SetVisible( false ); + + if ( m_Parameters[PORTALGUN_PORTAL2LIGHT_WORLD].SetMaterial( PORTALGUN_PORTAL2_FIRED_LAST_GLOW ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + // ------------------------------------------ + // Glows + // ------------------------------------------ + + const char *attachNamesGlow[NUM_GLOW_SPRITES] = + { + "Arm1_attach1", + "Arm1_attach2", + "Arm2_attach1", + "Arm2_attach2", + "Arm3_attach1", + "Arm3_attach2" + }; + + //Create the view glow sprites + for ( i = PORTALGUN_GLOW1; i < (PORTALGUN_GLOW1+NUM_GLOW_SPRITES); i++ ) + { + if ( m_Parameters[i].GetMaterial() != NULL ) + continue; + + m_Parameters[i].GetScale().SetAbsolute( 0.05f * SPRITE_SCALE ); + m_Parameters[i].GetAlpha().SetAbsolute( 24.0f ); + + // Different for different views + m_Parameters[i].SetAttachment( pModelView->LookupAttachment( attachNamesGlow[i-PORTALGUN_GLOW1] ) ); + m_Parameters[i].SetColor( Vector( 255, 128, 0 ) ); + m_Parameters[i].SetVisible( false ); + + if ( m_Parameters[i].SetMaterial( PORTALGUN_GLOW_SPRITE ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + //Create the world glow sprites + for ( i = PORTALGUN_GLOW1_WORLD; i < (PORTALGUN_GLOW1_WORLD+NUM_GLOW_SPRITES_WORLD); i++ ) + { + if ( m_Parameters[i].GetMaterial() != NULL ) + continue; + + m_Parameters[i].GetScale().SetAbsolute( 0.1f * SPRITE_SCALE ); + m_Parameters[i].GetAlpha().SetAbsolute( 24.0f ); + + // Different for different views + m_Parameters[i].SetAttachment( pModelWorld->LookupAttachment( attachNamesGlow[i-PORTALGUN_GLOW1_WORLD] ) ); + m_Parameters[i].SetColor( Vector( 255, 128, 0 ) ); + m_Parameters[i].SetVisible( false ); + + if ( m_Parameters[i].SetMaterial( PORTALGUN_GLOW_SPRITE ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + // ------------------------------------------ + // End caps + // ------------------------------------------ + + const char *attachNamesEndCap[NUM_ENDCAP_SPRITES] = + { + "Arm1_attach3", + "Arm2_attach3", + "Arm3_attach3", + }; + + //Create the endcap sprites + for ( i = PORTALGUN_ENDCAP1; i < (PORTALGUN_ENDCAP1+NUM_ENDCAP_SPRITES); i++ ) + { + if ( m_Parameters[i].GetMaterial() != NULL ) + continue; + + m_Parameters[i].GetScale().SetAbsolute( 0.02f * SPRITE_SCALE ); + m_Parameters[i].GetAlpha().SetAbsolute( 128.0f ); + m_Parameters[i].SetAttachment( pModelView->LookupAttachment( attachNamesEndCap[i-PORTALGUN_ENDCAP1] ) ); + m_Parameters[i].SetVisible( false ); + + if ( m_Parameters[i].SetMaterial( PORTALGUN_ENDCAP_SPRITE ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + //Create the world endcap sprites + for ( i = PORTALGUN_ENDCAP1_WORLD; i < (PORTALGUN_ENDCAP1_WORLD+NUM_ENDCAP_SPRITES_WORLD); i++ ) + { + if ( m_Parameters[i].GetMaterial() != NULL ) + continue; + + m_Parameters[i].GetScale().SetAbsolute( 0.04f * SPRITE_SCALE ); + m_Parameters[i].GetAlpha().SetAbsolute( 128.0f ); + m_Parameters[i].SetAttachment( pModelWorld->LookupAttachment( attachNamesEndCap[i-PORTALGUN_ENDCAP1_WORLD] ) ); + m_Parameters[i].SetVisible( false ); + + if ( m_Parameters[i].SetMaterial( PORTALGUN_ENDCAP_SPRITE ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + // ------------------------------------------ + // Internals + // ------------------------------------------ + + //Create the muzzle glow sprites + i = PORTALGUN_MUZZLE_GLOW; + + if ( m_Parameters[i].GetMaterial() == NULL ) + { + m_Parameters[i].GetScale().SetAbsolute( 0.025f * SPRITE_SCALE ); + m_Parameters[i].GetAlpha().SetAbsolute( 64.0f ); + m_Parameters[i].SetAttachment( pModelView->LookupAttachment( "Inside_effects" ) ); + m_Parameters[i].SetVisible( false ); + + if ( m_Parameters[i].SetMaterial( PORTALGUN_PORTAL_MUZZLE_GLOW_SPRITE ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + //Create the world muzzle glow sprites + i = PORTALGUN_MUZZLE_GLOW_WORLD; + + if ( m_Parameters[i].GetMaterial() == NULL ) + { + m_Parameters[i].GetScale().SetAbsolute( 0.025f * SPRITE_SCALE ); + m_Parameters[i].GetAlpha().SetAbsolute( 64.0f ); + m_Parameters[i].SetAttachment( pModelWorld->LookupAttachment( "Inside_effects" ) ); + m_Parameters[i].SetVisible( false ); + + if ( m_Parameters[i].SetMaterial( PORTALGUN_PORTAL_MUZZLE_GLOW_SPRITE ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + + // ------------------------------------------ + // Tube sprites + // ------------------------------------------ + + const char *attachNamesTubeBeam[NUM_TUBE_BEAM_SPRITES] = + { + "Beam_point1", + "Beam_point2", + "Beam_point3", + "Beam_point4", + "Beam_point5", + }; + + //Create the tube beam sprites + for ( i = PORTALGUN_TUBE_BEAM1; i < (PORTALGUN_TUBE_BEAM1+NUM_TUBE_BEAM_SPRITES); i++ ) + { + if ( m_Parameters[i].GetMaterial() == NULL ) + { + m_Parameters[i].GetScale().SetAbsolute( cl_portalgun_beam_size.GetFloat() * SPRITE_SCALE ); + m_Parameters[i].GetAlpha().SetAbsolute( 255.0f ); + m_Parameters[i].SetAttachment( pModelView->LookupAttachment( attachNamesTubeBeam[i-PORTALGUN_TUBE_BEAM1] ) ); + m_Parameters[i].SetVisible( false ); + + if ( m_Parameters[i].SetMaterial( PORTALGUN_PORTAL_TUBE_BEAM_SPRITE ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + } + + //Create the world tube beam sprites + for ( i = PORTALGUN_TUBE_BEAM1_WORLD; i < (PORTALGUN_TUBE_BEAM1_WORLD+NUM_TUBE_BEAM_SPRITES_WORLD); i++ ) + { + if ( m_Parameters[i].GetMaterial() == NULL ) + { + m_Parameters[i].GetScale().SetAbsolute( cl_portalgun_beam_size.GetFloat() * SPRITE_SCALE ); + m_Parameters[i].GetAlpha().SetAbsolute( 255.0f ); + m_Parameters[i].SetAttachment( pModelView->LookupAttachment( attachNamesTubeBeam[i-PORTALGUN_TUBE_BEAM1_WORLD] ) ); + m_Parameters[i].SetVisible( false ); + + if ( m_Parameters[i].SetMaterial( PORTALGUN_PORTAL_TUBE_BEAM_SPRITE ) == false ) + { + // This means the texture was not found + Assert( 0 ); + } + } + } + + // ------------------------------------------ + // Beams + // ------------------------------------------ + + // Setup the beams + int iBeam = 0; + + if ( pModelView != pModelWorld ) + { + m_Beams[iBeam++].Init( pModelView->LookupAttachment( "Arm1_attach3" ), pModelView->LookupAttachment( "muzzle" ), pModelView, true ); + m_Beams[iBeam++].Init( pModelView->LookupAttachment( "Arm2_attach3" ), pModelView->LookupAttachment( "muzzle" ), pModelView, true ); + m_Beams[iBeam++].Init( pModelView->LookupAttachment( "Arm3_attach3" ), pModelView->LookupAttachment( "muzzle" ), pModelView, true ); + } + else + { + iBeam += 3; + } + + m_Beams[iBeam++].Init( pModelWorld->LookupAttachment( "Arm1_attach3" ), pModelWorld->LookupAttachment( "muzzle" ), pModelWorld, false ); + m_Beams[iBeam++].Init( pModelWorld->LookupAttachment( "Arm2_attach3" ), pModelWorld->LookupAttachment( "muzzle" ), pModelWorld, false ); + m_Beams[iBeam++].Init( pModelWorld->LookupAttachment( "Arm3_attach3" ), pModelWorld->LookupAttachment( "muzzle" ), pModelWorld, false ); +} + +void C_WeaponPortalgun::DestroyEffects( void ) +{ + // Free our beams + for ( int i = 0; i < NUM_PORTALGUN_BEAMS; ++i ) + { + m_Beams[i].Release(); + } + + // Stop everything + StopEffects(); +} + +//----------------------------------------------------------------------------- +// Purpose: Ready effects +//----------------------------------------------------------------------------- +void C_WeaponPortalgun::DoEffectReady( void ) +{ + int i; + + // Turn on the glow sprites + for ( i = PORTALGUN_GLOW1; i < (PORTALGUN_GLOW1+NUM_GLOW_SPRITES); i++ ) + { + m_Parameters[i].GetScale().InitFromCurrent( 0.4f * SPRITE_SCALE, 0.2f ); + m_Parameters[i].GetAlpha().InitFromCurrent( 32.0f, 0.2f ); + m_Parameters[i].SetVisibleViewModel(); + } + + for ( i = PORTALGUN_GLOW1_WORLD; i < (PORTALGUN_GLOW1_WORLD+NUM_GLOW_SPRITES_WORLD); i++ ) + { + m_Parameters[i].GetScale().InitFromCurrent( 0.8f * SPRITE_SCALE, 0.4f ); + m_Parameters[i].GetAlpha().InitFromCurrent( 32.0f, 0.2f ); + m_Parameters[i].SetVisible3rdPerson(); + } + + // Turn on the endcap sprites + for ( i = PORTALGUN_ENDCAP1; i < (PORTALGUN_ENDCAP1+NUM_ENDCAP_SPRITES); i++ ) + { + m_Parameters[i].SetVisible( false ); + } + + // Turn on the world endcap sprites + for ( i = PORTALGUN_ENDCAP1_WORLD; i < (PORTALGUN_ENDCAP1_WORLD+NUM_ENDCAP_SPRITES_WORLD); i++ ) + { + m_Parameters[i].SetVisible( false ); + } + + // Turn on the internal sprites + i = PORTALGUN_MUZZLE_GLOW; + + Vector colorMagSprites = GetEffectColor( i ); + m_Parameters[i].SetColor( colorMagSprites ); + m_Parameters[i].SetVisibleViewModel(); + + // Turn on the world internal sprites + i = PORTALGUN_MUZZLE_GLOW_WORLD; + + m_Parameters[i].SetColor( colorMagSprites ); + m_Parameters[i].SetVisible3rdPerson(); + + // Turn on the tube beam sprites + for ( i = PORTALGUN_TUBE_BEAM1; i < (PORTALGUN_TUBE_BEAM1+NUM_TUBE_BEAM_SPRITES); i++ ) + { + m_Parameters[i].SetColor( colorMagSprites ); + m_Parameters[i].SetVisibleViewModel(); + } + + // Turn on the world tube beam sprites + for ( i = PORTALGUN_TUBE_BEAM1_WORLD; i < (PORTALGUN_TUBE_BEAM1_WORLD+NUM_TUBE_BEAM_SPRITES_WORLD); i++ ) + { + m_Parameters[i].SetColor( colorMagSprites ); + m_Parameters[i].SetVisible3rdPerson(); + } + + // Turn off beams off + for ( i = 0; i < NUM_PORTALGUN_BEAMS; ++i ) + { + m_Beams[i].SetVisibleViewModel( false ); + m_Beams[i].SetVisible3rdPerson( false ); + } + + CPortal_Player* pPlayer = (CPortal_Player*)GetOwner(); + if ( pPlayer ) + { + RumbleEffect( RUMBLE_PHYSCANNON_OPEN, 0, RUMBLE_FLAG_STOP ); + } +} + + +//----------------------------------------------------------------------------- +// Holding effects +//----------------------------------------------------------------------------- +void C_WeaponPortalgun::DoEffectHolding( void ) +{ + int i; + + // Turn on the glow sprites + for ( i = PORTALGUN_GLOW1; i < (PORTALGUN_GLOW1+NUM_GLOW_SPRITES); i++ ) + { + m_Parameters[i].GetScale().InitFromCurrent( 0.5f * SPRITE_SCALE, 0.2f ); + m_Parameters[i].GetAlpha().InitFromCurrent( 64.0f, 0.2f ); + m_Parameters[i].SetVisibleViewModel(); + } + + for ( i = PORTALGUN_GLOW1_WORLD; i < (PORTALGUN_GLOW1_WORLD+NUM_GLOW_SPRITES_WORLD); i++ ) + { + m_Parameters[i].GetScale().InitFromCurrent( 1.0f * SPRITE_SCALE, 0.4f ); + m_Parameters[i].GetAlpha().InitFromCurrent( 64.0f, 0.2f ); + m_Parameters[i].SetVisible3rdPerson(); + } + + // Turn on the endcap sprites + for ( i = PORTALGUN_ENDCAP1; i < (PORTALGUN_ENDCAP1+NUM_ENDCAP_SPRITES); i++ ) + { + m_Parameters[i].SetVisibleViewModel(); + } + + // Turn on the world endcap sprites + for ( i = PORTALGUN_ENDCAP1_WORLD; i < (PORTALGUN_ENDCAP1_WORLD+NUM_ENDCAP_SPRITES_WORLD); i++ ) + { + m_Parameters[i].SetVisible3rdPerson(); + } + + // Turn on the internal sprites + i = PORTALGUN_MUZZLE_GLOW; + + Vector colorMagSprites = GetEffectColor( i ); + m_Parameters[i].SetColor( colorMagSprites ); + m_Parameters[i].SetVisibleViewModel(); + + // Turn on the world internal sprites + i = PORTALGUN_MUZZLE_GLOW_WORLD; + + m_Parameters[i].SetColor( colorMagSprites ); + m_Parameters[i].SetVisible3rdPerson(); + + // Turn on the tube beam sprites + for ( i = PORTALGUN_TUBE_BEAM1; i < (PORTALGUN_TUBE_BEAM1+NUM_TUBE_BEAM_SPRITES); i++ ) + { + m_Parameters[i].SetColor( colorMagSprites ); + m_Parameters[i].SetVisibleViewModel(); + } + + // Turn on the world tube beam sprites + for ( i = PORTALGUN_TUBE_BEAM1; i < (PORTALGUN_TUBE_BEAM1+NUM_TUBE_BEAM_SPRITES); i++ ) + { + m_Parameters[i].SetColor( colorMagSprites ); + m_Parameters[i].SetVisible3rdPerson(); + } + + // Set beams them visible + for ( i = 0; i < NUM_PORTALGUN_BEAMS / 2; ++i ) + { + m_Beams[i].SetVisible3rdPerson( false ); + m_Beams[i].SetVisibleViewModel(); + m_Beams[i].SetBrightness( 128.0f ); + } + + for ( i; i < NUM_PORTALGUN_BEAMS; ++i ) + { + m_Beams[i].SetVisibleViewModel( false ); + m_Beams[i].SetVisible3rdPerson(); + m_Beams[i].SetBrightness( 128.0f ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Shutdown for the weapon when it's holstered +//----------------------------------------------------------------------------- +void C_WeaponPortalgun::DoEffectNone( void ) +{ + int i; + + //Turn off main glows + m_Parameters[PORTALGUN_GRAVLIGHT].SetVisible( false ); + m_Parameters[PORTALGUN_GRAVLIGHT_WORLD].SetVisible( false ); + m_Parameters[PORTALGUN_PORTAL1LIGHT].SetVisible( false ); + m_Parameters[PORTALGUN_PORTAL1LIGHT_WORLD].SetVisible( false ); + m_Parameters[PORTALGUN_PORTAL2LIGHT].SetVisible( false ); + m_Parameters[PORTALGUN_PORTAL1LIGHT_WORLD].SetVisible( false ); + + for ( i = PORTALGUN_GLOW1; i < (PORTALGUN_GLOW1+NUM_GLOW_SPRITES); i++ ) + { + m_Parameters[i].SetVisible( false ); + } + + for ( i = PORTALGUN_GLOW1_WORLD; i < (PORTALGUN_GLOW1_WORLD+NUM_GLOW_SPRITES_WORLD); i++ ) + { + m_Parameters[i].SetVisible( false ); + } + + for ( i = PORTALGUN_ENDCAP1; i < (PORTALGUN_ENDCAP1+NUM_ENDCAP_SPRITES); i++ ) + { + m_Parameters[i].SetVisible( false ); + } + + for ( i = PORTALGUN_ENDCAP1_WORLD; i < (PORTALGUN_ENDCAP1_WORLD+NUM_ENDCAP_SPRITES_WORLD); i++ ) + { + m_Parameters[i].SetVisible( false ); + } + + m_Parameters[PORTALGUN_MUZZLE_GLOW].SetVisible( false ); + m_Parameters[PORTALGUN_MUZZLE_GLOW_WORLD].SetVisible( false ); + + for ( i = PORTALGUN_TUBE_BEAM1; i < (PORTALGUN_TUBE_BEAM1+NUM_TUBE_BEAM_SPRITES); i++ ) + { + m_Parameters[i].SetVisible( false ); + } + + for ( i = PORTALGUN_TUBE_BEAM1_WORLD; i < (PORTALGUN_TUBE_BEAM1_WORLD+NUM_TUBE_BEAM_SPRITES_WORLD); i++ ) + { + m_Parameters[i].SetVisible( false ); + } + + for ( i = 0; i < NUM_PORTALGUN_BEAMS; ++i ) + { + m_Beams[i].SetVisibleViewModel( false ); + m_Beams[i].SetVisible3rdPerson( false ); + } +} + +void C_WeaponPortalgun::OnPreDataChanged( DataUpdateType_t updateType ) +{ + //PreDataChanged.m_matrixThisToLinked = m_matrixThisToLinked; + m_bOldCanFirePortal1 = m_bCanFirePortal1; + m_bOldCanFirePortal1 = m_bCanFirePortal2; + + BaseClass::OnPreDataChanged( updateType ); +} + +void C_WeaponPortalgun::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + if ( updateType == DATA_UPDATE_CREATED ) + { + // Start thinking (Baseclass stops it) + SetNextClientThink( CLIENT_THINK_ALWAYS ); + + { + C_BaseAnimating::AutoAllowBoneAccess boneaccess( true, true ); + StartEffects(); + } + + DoEffect( m_EffectState ); + } + + // Update effect state when out of parity with the server + else if ( m_nOldEffectState != m_EffectState || m_bOldCanFirePortal1 != m_bCanFirePortal1 || m_bOldCanFirePortal2 != m_bCanFirePortal2 ) + { + DoEffect( m_EffectState ); + m_nOldEffectState = m_EffectState; + + m_bOldCanFirePortal1 = m_bCanFirePortal1; + m_bOldCanFirePortal2 = m_bCanFirePortal2; + } +} + +void C_WeaponPortalgun::ClientThink( void ) +{ + CPortal_Player *pPlayer = ToPortalPlayer( GetOwner() ); + + if ( pPlayer && dynamic_cast<C_WeaponPortalgun*>( pPlayer->GetActiveWeapon() ) ) + { + if ( m_EffectState == EFFECT_NONE ) + { + //DoEffect( ( GetPlayerHeldEntity( pPlayer ) ) ? ( EFFECT_HOLDING ) : ( EFFECT_READY ) ); + } + + if ( m_EffectState != EFFECT_NONE ) + { + // Showing a special color for holding is confusing... just use the last fired color -Jeep + + //if ( m_bOpenProngs ) + //{ + // //Turn on the grav light + // m_Parameters[PORTALGUN_GRAVLIGHT].SetVisibleViewModel(); + // m_Parameters[PORTALGUN_GRAVLIGHT_WORLD].SetVisible3rdPerson(); + + // m_Parameters[PORTALGUN_PORTAL1LIGHT].SetVisibleViewModel( false ); + // m_Parameters[PORTALGUN_PORTAL1LIGHT_WORLD].SetVisible3rdPerson( false ); + // m_Parameters[PORTALGUN_PORTAL2LIGHT].SetVisibleViewModel( false ); + // m_Parameters[PORTALGUN_PORTAL2LIGHT_WORLD].SetVisible3rdPerson( false ); + //} + //else + { + m_Parameters[PORTALGUN_GRAVLIGHT].SetVisibleViewModel( false ); + m_Parameters[PORTALGUN_GRAVLIGHT_WORLD].SetVisible3rdPerson( false ); + + //Turn on and off the correct fired last lights + m_Parameters[PORTALGUN_PORTAL1LIGHT].SetVisibleViewModel( m_iLastFiredPortal == 1 ); + m_Parameters[PORTALGUN_PORTAL1LIGHT_WORLD].SetVisible3rdPerson( m_iLastFiredPortal == 1 ); + m_Parameters[PORTALGUN_PORTAL2LIGHT].SetVisibleViewModel( m_iLastFiredPortal == 2 ); + m_Parameters[PORTALGUN_PORTAL2LIGHT_WORLD].SetVisible3rdPerson( m_iLastFiredPortal == 2 ); + } + } + } + + // Update our effects + DoEffectIdle(); + + NetworkStateChanged(); +} + +Vector C_WeaponPortalgun::GetEffectColor( int iPalletIndex ) +{ + Color color; + + // Showing a special color for holding is confusing... just use the last fired color -Jeep + /*if ( m_bOpenProngs ) + { + color = UTIL_Portal_Color( 0 ); + } + else */if ( m_iLastFiredPortal == 1 ) + { + color = UTIL_Portal_Color( 1 ); + } + else if ( m_iLastFiredPortal == 2 ) + { + color = UTIL_Portal_Color( 2 ); + } + else + { + color = Color( 128, 128, 128, 255 ); + } + + Vector vColor; + vColor.x = color.r(); + vColor.y = color.g(); + vColor.z = color.b(); + + return vColor; +} + +extern void FormatViewModelAttachment( Vector &vOrigin, bool bInverse ); + +//----------------------------------------------------------------------------- +// Purpose: Gets the complete list of values needed to render an effect from an +// effect parameter +//----------------------------------------------------------------------------- +void C_WeaponPortalgun::GetEffectParameters( EffectType_t effectID, color32 &color, float &scale, IMaterial **pMaterial, Vector &vecAttachment, bool b3rdPerson ) +{ + const float dt = gpGlobals->curtime; + + // Get alpha + float alpha = m_Parameters[effectID].GetAlpha().Interp( dt ); + + // Get scale + scale = m_Parameters[effectID].GetScale().Interp( dt ); + + // Get material + *pMaterial = (IMaterial *) m_Parameters[effectID].GetMaterial(); + + // Setup the color + color.r = (int) m_Parameters[effectID].GetColor().x; + color.g = (int) m_Parameters[effectID].GetColor().y; + color.b = (int) m_Parameters[effectID].GetColor().z; + color.a = (int) alpha; + + // Setup the attachment + int attachment = m_Parameters[effectID].GetAttachment(); + QAngle angles; + + // Format for first-person + CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); + + if ( pOwner != NULL ) + { + C_BaseAnimating *pModel; + int originalModelIndex = 0; + + if ( b3rdPerson ) + { + pModel = this; + originalModelIndex = GetModelIndex(); + SetModelIndex( GetWorldModelIndex() ); + } + else + { + pModel = pOwner->GetViewModel(); + } + + pModel->GetAttachment( attachment, vecAttachment, angles ); + + if ( !b3rdPerson ) + { + ::FormatViewModelAttachment( vecAttachment, true ); + } + else + { + SetModelIndex( originalModelIndex ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Whether or not an effect is set to display +//----------------------------------------------------------------------------- +bool C_WeaponPortalgun::IsEffectVisible( EffectType_t effectID, bool b3rdPerson ) +{ + if ( b3rdPerson ) + { + return m_Parameters[effectID].IsVisible3rdPerson(); + } + else + { + return m_Parameters[effectID].IsVisibleViewModel(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draws the effect sprite, given an effect parameter ID +//----------------------------------------------------------------------------- +void C_WeaponPortalgun::DrawEffectSprite( EffectType_t effectID, bool b3rdPerson ) +{ + color32 color; + float scale; + IMaterial *pMaterial; + Vector vecAttachment; + + // Don't draw invisible effects + if ( !IsEffectVisible( effectID, b3rdPerson ) ) + return; + + // Get all of our parameters + GetEffectParameters( effectID, color, scale, &pMaterial, vecAttachment, b3rdPerson ); + + // Don't render fully translucent objects + if ( color.a <= 0.0f ) + return; + + // Draw the sprite + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->Bind( pMaterial, this ); + DrawSprite( vecAttachment, scale, scale, color ); +} + +//----------------------------------------------------------------------------- +// Purpose: Render our third-person effects +//----------------------------------------------------------------------------- +void C_WeaponPortalgun::DrawEffects( bool b3rdPerson ) +{ + for ( int i = 0; i < NUM_PORTALGUN_PARAMETERS; i++ ) + { + DrawEffectSprite( (EffectType_t) i, b3rdPerson ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Third-person function call to render world model +//----------------------------------------------------------------------------- +int C_WeaponPortalgun::DrawModel( int flags ) +{ + // Only render these on the transparent pass + /*if ( flags & STUDIO_TRANSPARENCY ) + { + DrawEffects( true ); + return 1; + }*/ + + int iRetValue = BaseClass::DrawModel( flags ); + + if ( iRetValue ) + { + DrawEffects( true ); + } + + return iRetValue; +} + +//----------------------------------------------------------------------------- +// Purpose: First-person function call after viewmodel has been drawn +//----------------------------------------------------------------------------- +void C_WeaponPortalgun::ViewModelDrawn( C_BaseViewModel *pBaseViewModel ) +{ + // Render our effects + DrawEffects( false ); + + // Pass this back up + BaseClass::ViewModelDrawn( pBaseViewModel ); +} + +void UpdatePoseParameter( C_BaseAnimating *pBaseAnimating, int iPose, float fValue ) +{ + pBaseAnimating->SetPoseParameter( iPose, fValue ); +} + +void InterpToward( float *pfCurrent, float fGoal, float fRate ) +{ + if ( *pfCurrent < fGoal ) + { + *pfCurrent += fRate; + + if ( *pfCurrent > fGoal ) + { + *pfCurrent = fGoal; + } + } + else if ( *pfCurrent > fGoal ) + { + *pfCurrent -= fRate; + + if ( *pfCurrent < fGoal ) + { + *pfCurrent = fGoal; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Idle effect (pulsing) +//----------------------------------------------------------------------------- +void C_WeaponPortalgun::DoEffectIdle( void ) +{ + StartEffects(); + + int i; + + // Turn on the glow sprites + for ( i = PORTALGUN_GLOW1; i < (PORTALGUN_GLOW1+NUM_GLOW_SPRITES); i++ ) + { + m_Parameters[i].GetScale().InitFromCurrent( RandomFloat( 0.0075f, 0.05f ) * SPRITE_SCALE, 0.1f ); + m_Parameters[i].GetAlpha().SetAbsolute( RandomInt( 10, 24 ) ); + } + + // Turn on the world glow sprites + for ( i = PORTALGUN_GLOW1_WORLD; i < (PORTALGUN_GLOW1_WORLD+NUM_GLOW_SPRITES_WORLD); i++ ) + { + m_Parameters[i].GetScale().InitFromCurrent( RandomFloat( 0.015f, 0.1f ) * SPRITE_SCALE, 0.1f ); + m_Parameters[i].GetAlpha().SetAbsolute( RandomInt( 10, 24 ) ); + } + + // Turn on the endcap sprites + for ( i = PORTALGUN_ENDCAP1; i < (PORTALGUN_ENDCAP1+NUM_ENDCAP_SPRITES); i++ ) + { + m_Parameters[i].GetScale().SetAbsolute( RandomFloat( 1.0f, 3.0f ) ); + m_Parameters[i].GetAlpha().SetAbsolute( RandomInt( 96, 128 ) ); + } + + // Turn on the world endcap sprites + for ( i = PORTALGUN_ENDCAP1_WORLD; i < (PORTALGUN_ENDCAP1_WORLD+NUM_ENDCAP_SPRITES_WORLD); i++ ) + { + m_Parameters[i].GetScale().SetAbsolute( RandomFloat( 2.0f, 6.0f ) ); + m_Parameters[i].GetAlpha().SetAbsolute( RandomInt( 96, 128 ) ); + } + + // Turn on the internal sprites + i = PORTALGUN_MUZZLE_GLOW; + + if ( m_bPulseUp ) + { + m_fPulse += gpGlobals->frametime; + if ( m_fPulse > 1.0f ) + { + m_fPulse = 1.0f; + m_bPulseUp = !m_bPulseUp; + } + } + else + { + m_fPulse -= gpGlobals->frametime; + if ( m_fPulse < 0.0f ) + { + m_fPulse = 0.0f; + m_bPulseUp = !m_bPulseUp; + } + } + + m_Parameters[i].GetScale().SetAbsolute( cl_portalgun_effects_min_size.GetFloat() + ( m_fEffectsMaxSize1 - cl_portalgun_effects_min_size.GetFloat() ) * m_fPulse ); + m_Parameters[i].GetAlpha().SetAbsolute( cl_portalgun_effects_min_alpha.GetInt() + ( cl_portalgun_effects_max_alpha.GetInt() - cl_portalgun_effects_min_alpha.GetInt() ) * m_fPulse ); + Vector colorMagSprites = GetEffectColor( i ); + m_Parameters[i].SetColor( colorMagSprites ); + + // Turn on the world internal sprites + i = PORTALGUN_MUZZLE_GLOW_WORLD; + + m_Parameters[i].GetScale().SetAbsolute( cl_portalgun_effects_min_size.GetFloat() + ( m_fEffectsMaxSize1 - cl_portalgun_effects_min_size.GetFloat() ) * m_fPulse ); + m_Parameters[i].GetAlpha().SetAbsolute( cl_portalgun_effects_min_alpha.GetInt() + ( cl_portalgun_effects_max_alpha.GetInt() - cl_portalgun_effects_min_alpha.GetInt() ) * m_fPulse ); + m_Parameters[i].SetColor( colorMagSprites ); + + // Turn on the tube beam sprites + for ( i = PORTALGUN_TUBE_BEAM1; i < (PORTALGUN_TUBE_BEAM1+NUM_TUBE_BEAM_SPRITES); i++ ) + { + m_Parameters[i].GetAlpha().SetAbsolute( cl_portalgun_effects_min_alpha.GetInt() + ( cl_portalgun_effects_max_alpha.GetInt() - cl_portalgun_effects_min_alpha.GetInt() ) * m_fPulse ); + m_Parameters[i].SetColor( colorMagSprites ); + } + + // Turn on the world tube beam sprites + for ( i = PORTALGUN_TUBE_BEAM1_WORLD; i < (PORTALGUN_TUBE_BEAM1_WORLD+NUM_TUBE_BEAM_SPRITES_WORLD); i++ ) + { + m_Parameters[i].GetAlpha().SetAbsolute( cl_portalgun_effects_min_alpha.GetInt() + ( cl_portalgun_effects_max_alpha.GetInt() - cl_portalgun_effects_min_alpha.GetInt() ) * m_fPulse ); + m_Parameters[i].SetColor( colorMagSprites ); + } +} |