CBaseHandle CPortalGameMovement::TestPlayerPosition( const Vector& pos, int collisionGroup, trace_t& pm ) { TracePlayerBBox( pos, pos, MASK_PLAYERSOLID, collisionGroup, pm ); //hook into the existing portal special trace functionality //Ray_t ray; //ray.Init( pos, pos, GetPlayerMins(), GetPlayerMaxs() ); //UTIL_TraceRay( ray, MASK_PLAYERSOLID, mv->m_nPlayerHandle.Get(), collisionGroup, &pm ); if( pm.startsolid && pm.m_pEnt && (pm.contents & MASK_PLAYERSOLID) ) { #ifdef _DEBUG AssertMsgOnce( false, "The player got stuck on something. Break to investigate." ); //happens enough to just leave in a perma-debugger //this next trace is PURELY for tracking down how the player got stuck. Nothing new is discovered over the same trace about 10 lines up TracePlayerBBox( pos, pos, MASK_PLAYERSOLID, collisionGroup, pm ); #endif return pm.m_pEnt->GetRefEHandle(); } #ifndef CLIENT_DLL else if ( pm.startsolid && pm.m_pEnt && CPSCollisionEntity::IsPortalSimulatorCollisionEntity( pm.m_pEnt ) ) { // Stuck in a portal environment object, so unstick them! CPortal_Player *pPortalPlayer = (CPortal_Player *)((CBaseEntity *)mv->m_nPlayerHandle.Get()); pPortalPlayer->SetStuckOnPortalCollisionObject(); return INVALID_EHANDLE_INDEX; } #endif else { return INVALID_EHANDLE_INDEX; } }
void CFunc_LiquidPortal::TeleportImmersedEntity( CBaseEntity *pEntity ) { if( pEntity == NULL ) return; if( pEntity->IsPlayer() ) { CPortal_Player *pEntityAsPlayer = (CPortal_Player *)pEntity; Vector vNewOrigin = m_matrixThisToLinked * pEntity->GetAbsOrigin(); QAngle qNewAngles = TransformAnglesToWorldSpace( pEntityAsPlayer->EyeAngles(), m_matrixThisToLinked.As3x4() ); Vector vNewVelocity = m_matrixThisToLinked.ApplyRotation( pEntity->GetAbsVelocity() ); pEntity->Teleport( &vNewOrigin, &qNewAngles, &vNewVelocity ); pEntityAsPlayer->m_hSurroundingLiquidPortal = m_hLinkedPortal; } else { Vector vNewOrigin = m_matrixThisToLinked * pEntity->GetAbsOrigin(); QAngle qNewAngles = TransformAnglesToWorldSpace( pEntity->GetAbsAngles(), m_matrixThisToLinked.As3x4() ); Vector vNewVelocity = m_matrixThisToLinked.ApplyRotation( pEntity->GetAbsVelocity() ); pEntity->Teleport( &vNewOrigin, &qNewAngles, &vNewVelocity ); } }
static void change_portalgun_linkage_id_f( const CCommand &args ) { if( sv_cheats->GetBool() == false ) //heavy handed version since setting the concommand with FCVAR_CHEATS isn't working like I thought return; if( args.ArgC() < 2 ) return; unsigned char iNewID = (unsigned char)atoi( args[1] ); CPortal_Player *pPlayer = (CPortal_Player *)UTIL_GetCommandClient(); int iWeaponCount = pPlayer->WeaponCount(); for( int i = 0; i != iWeaponCount; ++i ) { CBaseCombatWeapon *pWeapon = pPlayer->GetWeapon(i); if( pWeapon == NULL ) continue; if( dynamic_cast<CWeaponPortalgun *>(pWeapon) != NULL ) { CWeaponPortalgun *pPortalGun = (CWeaponPortalgun *)pWeapon; pPortalGun->m_iPortalLinkageGroupID = iNewID; break; } } }
void CPortalGameMovement::FunnelIntoPortal( CProp_Portal *pPortal, Vector &wishdir ) { // Make sure there's a portal if ( !pPortal ) return; // Get portal vectors Vector vPortalForward, vPortalRight, vPortalUp; pPortal->GetVectors( &vPortalForward, &vPortalRight, &vPortalUp ); // Make sure it's a floor portal if ( vPortalForward.z < 0.8f ) return; vPortalRight.z = 0.0f; vPortalUp.z = 0.0f; VectorNormalize( vPortalRight ); VectorNormalize( vPortalUp ); // Make sure the player is looking downward CPortal_Player *pPlayer = GetPortalPlayer(); Vector vPlayerForward; pPlayer->EyeVectors( &vPlayerForward ); if ( vPlayerForward.z > -0.1f ) return; Vector vPlayerOrigin = pPlayer->GetAbsOrigin(); Vector vPlayerToPortal = pPortal->GetAbsOrigin() - vPlayerOrigin; // Make sure the player is trying to air control, they're falling downward and they are vertically close to the portal if ( fabsf( wishdir[ 0 ] ) > 64.0f || fabsf( wishdir[ 1 ] ) > 64.0f || mv->m_vecVelocity[ 2 ] > -165.0f || vPlayerToPortal.z < -512.0f ) return; // Make sure we're in the 2D portal rectangle if ( ( vPlayerToPortal.Dot( vPortalRight ) * vPortalRight ).Length() > PORTAL_HALF_WIDTH * 1.5f ) return; if ( ( vPlayerToPortal.Dot( vPortalUp ) * vPortalUp ).Length() > PORTAL_HALF_HEIGHT * 1.5f ) return; if ( vPlayerToPortal.z > -8.0f ) { // We're too close the the portal to continue correcting, but zero the velocity so our fling velocity is nice mv->m_vecVelocity[ 0 ] = 0.0f; mv->m_vecVelocity[ 1 ] = 0.0f; } else { // Funnel toward the portal float fFunnelX = vPlayerToPortal.x * PORTAL_FUNNEL_AMOUNT - mv->m_vecVelocity[ 0 ]; float fFunnelY = vPlayerToPortal.y * PORTAL_FUNNEL_AMOUNT - mv->m_vecVelocity[ 1 ]; wishdir[ 0 ] += fFunnelX; wishdir[ 1 ] += fFunnelY; } }
//----------------------------------------------------------------------------- // Purpose: // Input : event - //----------------------------------------------------------------------------- void CPortalPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData ) { Activity iWeaponActivity = ACT_INVALID; switch( event ) { case PLAYERANIMEVENT_ATTACK_PRIMARY: case PLAYERANIMEVENT_ATTACK_SECONDARY: { CPortal_Player *pPlayer = GetPortalPlayer(); if ( !pPlayer ) return; CWeaponPortalBase *pWpn = pPlayer->GetActivePortalWeapon(); if ( pWpn ) { // Weapon primary fire. if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_PRIMARYFIRE ); } else { RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE ); } iWeaponActivity = ACT_VM_PRIMARYATTACK; } else // unarmed player { } break; } default: { BaseClass::DoAnimationEvent( event, nData ); break; } } #ifdef CLIENT_DLL // Make the weapon play the animation as well if ( iWeaponActivity != ACT_INVALID ) { CBaseCombatWeapon *pWeapon = GetPortalPlayer()->GetActiveWeapon(); if ( pWeapon ) { pWeapon->SendWeaponAnim( iWeaponActivity ); } } #endif }
void CC_UpgradePortalGun( void ) { CPortal_Player *pPlayer = ToPortalPlayer( UTIL_GetCommandClient() ); CWeaponPortalgun *pPortalGun = static_cast<CWeaponPortalgun*>( pPlayer->Weapon_OwnsThisType( "weapon_portalgun" ) ); if ( pPortalGun ) { pPortalGun->SetCanFirePortal1(); pPortalGun->SetCanFirePortal2(); } }
void ClientActive( edict_t *pEdict, bool bLoadGame ) { CPortal_Player *pPlayer = dynamic_cast< CPortal_Player* >( CBaseEntity::Instance( pEdict ) ); Assert( pPlayer ); pPlayer->InitialSpawn(); if ( !bLoadGame ) { pPlayer->Spawn(); } }
void CWeaponPortalgun::Think( void ) { //Allow descended classes a chance to do something before the think function if ( PreThink() ) return; SetNextThink( gpGlobals->curtime + 0.1f ); CPortal_Player *pPlayer = ToPortalPlayer( GetOwner() ); if ( !pPlayer || pPlayer->GetActiveWeapon() != this ) { m_fCanPlacePortal1OnThisSurface = 1.0f; m_fCanPlacePortal2OnThisSurface = 1.0f; return; } // Test portal placement m_fCanPlacePortal1OnThisSurface = ( ( m_bCanFirePortal1 ) ? ( FirePortal( false, 0, 1 ) ) : ( 0.0f ) ); m_fCanPlacePortal2OnThisSurface = ( ( m_bCanFirePortal2 ) ? ( FirePortal( true, 0, 2 ) ) : ( 0.0f ) ); // Draw obtained portal color chips int iSlot1State = ( ( m_bCanFirePortal1 ) ? ( 0 ) : ( 1 ) ); // FIXME: Portal gun might have only red but not blue; int iSlot2State = ( ( m_bCanFirePortal2 ) ? ( 0 ) : ( 1 ) ); SetBodygroup( 1, iSlot1State ); SetBodygroup( 2, iSlot2State ); if ( pPlayer->GetViewModel() ) { pPlayer->GetViewModel()->SetBodygroup( 1, iSlot1State ); pPlayer->GetViewModel()->SetBodygroup( 2, iSlot2State ); } // HACK HACK! Used to make the gun visually change when going through a cleanser! if ( m_fEffectsMaxSize1 > 4.0f ) { m_fEffectsMaxSize1 -= gpGlobals->frametime * 400.0f; if ( m_fEffectsMaxSize1 < 4.0f ) m_fEffectsMaxSize1 = 4.0f; } if ( m_fEffectsMaxSize2 > 4.0f ) { m_fEffectsMaxSize2 -= gpGlobals->frametime * 400.0f; if ( m_fEffectsMaxSize2 < 4.0f ) m_fEffectsMaxSize2 = 4.0f; } }
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(); }
int CPortalGameMovement::CheckStuck( void ) { if( BaseClass::CheckStuck() ) { CPortal_Player *pPortalPlayer = GetPortalPlayer(); #ifndef CLIENT_DLL if( pPortalPlayer->IsAlive() ) g_PortalGameStats.Event_PlayerStuck( pPortalPlayer ); #endif //try to fix it, then recheck Vector vIndecisive; if( pPortalPlayer->m_hPortalEnvironment ) { pPortalPlayer->m_hPortalEnvironment->GetVectors( &vIndecisive, NULL, NULL ); } else { vIndecisive.Init( 0.0f, 0.0f, 1.0f ); } Vector ptOldOrigin = pPortalPlayer->GetAbsOrigin(); if( pPortalPlayer->m_hPortalEnvironment ) { if( !FindClosestPassableSpace( pPortalPlayer, vIndecisive ) ) { #ifndef CLIENT_DLL DevMsg( "Hurting the player for FindClosestPassableSpaceFailure!" ); CTakeDamageInfo info( pPortalPlayer, pPortalPlayer, vec3_origin, vec3_origin, 1e10, DMG_CRUSH ); pPortalPlayer->OnTakeDamage( info ); #endif } //make sure we didn't get put behind the portal >_< Vector ptCurrentOrigin = pPortalPlayer->GetAbsOrigin(); if( vIndecisive.Dot( ptCurrentOrigin - ptOldOrigin ) < 0.0f ) { pPortalPlayer->SetAbsOrigin( ptOldOrigin + (vIndecisive * 5.0f) ); //this is an anti-bug hack, since this would have probably popped them out of the world, we're just going to move them forward a few units } } mv->SetAbsOrigin( pPortalPlayer->GetAbsOrigin() ); return BaseClass::CheckStuck(); } else { return 0; } }
float CWeaponPortalgun::FirePortal( bool bPortal2, Vector *pVector /*= 0*/, bool bTest /*= false*/ ) { bool bPlayer = false; Vector vEye; Vector vDirection; Vector vTracerOrigin; CBaseEntity *pOwner = GetOwner(); if ( pOwner && pOwner->IsPlayer() ) { bPlayer = true; } if( bPlayer ) { CPortal_Player *pPlayer = (CPortal_Player *)pOwner; if ( !bTest && pPlayer ) { pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY, 0 ); } Vector forward, right, up; AngleVectors( pPlayer->EyeAngles(), &forward, &right, &up ); pPlayer->EyeVectors( &vDirection, NULL, NULL ); vEye = pPlayer->EyePosition(); // Check if the players eye is behind the portal they're in and translate it VMatrix matThisToLinked; CProp_Portal *pPlayerPortal = pPlayer->m_hPortalEnvironment; if ( pPlayerPortal ) { Vector ptPortalCenter; Vector vPortalForward; ptPortalCenter = pPlayerPortal->GetAbsOrigin(); pPlayerPortal->GetVectors( &vPortalForward, NULL, NULL ); Vector vEyeToPortalCenter = ptPortalCenter - vEye; float fPortalDist = vPortalForward.Dot( vEyeToPortalCenter ); if( fPortalDist > 0.0f ) { // Eye is behind the portal matThisToLinked = pPlayerPortal->MatrixThisToLinked(); } else { pPlayerPortal = NULL; } } if ( pPlayerPortal ) { UTIL_Portal_VectorTransform( matThisToLinked, forward, forward ); UTIL_Portal_VectorTransform( matThisToLinked, right, right ); UTIL_Portal_VectorTransform( matThisToLinked, up, up ); UTIL_Portal_VectorTransform( matThisToLinked, vDirection, vDirection ); UTIL_Portal_PointTransform( matThisToLinked, vEye, vEye ); if ( pVector ) { UTIL_Portal_VectorTransform( matThisToLinked, *pVector, *pVector ); } } vTracerOrigin = vEye + forward * 30.0f + right * 4.0f + up * (-5.0f); } else { // This portalgun is not held by the player-- Fire using the muzzle attachment Vector vecShootOrigin; QAngle angShootDir; GetAttachment( LookupAttachment( "muzzle" ), vecShootOrigin, angShootDir ); vEye = vecShootOrigin; vTracerOrigin = vecShootOrigin; AngleVectors( angShootDir, &vDirection, NULL, NULL ); } if ( !bTest ) { SendWeaponAnim( ACT_VM_PRIMARYATTACK ); } if ( pVector ) { vDirection = *pVector; } Vector vTraceStart = vEye + (vDirection * m_fMinRange1); Vector vFinalPosition; QAngle qFinalAngles; PortalPlacedByType ePlacedBy = ( bPlayer ) ? ( PORTAL_PLACED_BY_PLAYER ) : ( PORTAL_PLACED_BY_PEDESTAL ); trace_t tr; float fPlacementSuccess = TraceFirePortal( bPortal2, vTraceStart, vDirection, tr, vFinalPosition, qFinalAngles, ePlacedBy, bTest ); if ( sv_portal_placement_never_fail.GetBool() ) { fPlacementSuccess = 1.0f; } if ( !bTest ) { CProp_Portal *pPortal = CProp_Portal::FindPortal( m_iPortalLinkageGroupID, bPortal2, true ); // If it was a failure, put the effect at exactly where the player shot instead of where the portal bumped to if ( fPlacementSuccess < 0.5f ) vFinalPosition = tr.endpos; pPortal->PlacePortal( vFinalPosition, qFinalAngles, fPlacementSuccess, true ); float fDelay = vTracerOrigin.DistTo( tr.endpos ) / ( ( bPlayer ) ? ( BLAST_SPEED ) : ( BLAST_SPEED_NON_PLAYER ) ); QAngle qFireAngles; VectorAngles( vDirection, qFireAngles ); DoEffectBlast( pPortal->m_bIsPortal2, ePlacedBy, vTracerOrigin, vFinalPosition, qFireAngles, fDelay ); pPortal->SetContextThink( &CProp_Portal::DelayedPlacementThink, gpGlobals->curtime + fDelay, s_pDelayedPlacementContext ); pPortal->m_vDelayedPosition = vFinalPosition; pPortal->m_hPlacedBy = this; } return fPlacementSuccess; }
/* =========== ClientPutInServer called each time a player is spawned into the game ============ */ void ClientPutInServer( edict_t *pEdict, const char *playername ) { // Allocate a CBasePlayer for pev, and call spawn CPortal_Player *pPlayer = CPortal_Player::CreatePlayer( "player", pEdict ); pPlayer->PlayerData()->netname = AllocPooledString( playername ); }